├── .gitignore ├── README.md ├── composer.json ├── composer.lock ├── config └── front.php ├── install-stubs ├── base-filter.php ├── base-page.php ├── base-resource.php ├── filter.php ├── page.php ├── search-filter.php └── sidebar.blade.php ├── resources ├── lang │ └── es.json └── views │ ├── cards │ └── numeric.blade.php │ ├── components │ ├── cards.blade.php │ ├── line.blade.php │ ├── panel-form.blade.php │ ├── panel.blade.php │ └── welcome.blade.php │ ├── crud │ ├── action.blade.php │ ├── create.blade.php │ ├── edit.blade.php │ ├── index.blade.php │ ├── massive-edit.blade.php │ ├── massive-index-edit.blade.php │ ├── partial-create.blade.php │ ├── partial-index.blade.php │ └── show.blade.php │ ├── elements │ ├── breadcrumbs.blade.php │ ├── errors.blade.php │ ├── object_actions.blade.php │ ├── relation_filters.blade.php │ ├── total_results.blade.php │ └── views_buttons.blade.php │ ├── input-form.blade.php │ ├── input-group.blade.php │ ├── input-outer.blade.php │ ├── input-show.blade.php │ ├── inputs │ ├── file.blade.php │ ├── image-form.blade.php │ ├── image.blade.php │ └── images-form.blade.php │ ├── layout.blade.php │ ├── page.blade.php │ ├── partials │ └── user-navbar.blade.php │ └── texts │ ├── alert.blade.php │ ├── button.blade.php │ ├── heading.blade.php │ ├── horizontal-description.blade.php │ ├── paragraph.blade.php │ ├── table.blade.php │ └── title.blade.php └── src ├── Actions ├── Action.php └── IndexAction.php ├── ButtonManager.php ├── Cards ├── Card.php └── NumericCard.php ├── Components ├── Component.php ├── FrontCreate.php ├── FrontIndex.php ├── HtmlableComponent.php ├── Line.php ├── Panel.php ├── ShowCards.php ├── View.php └── Welcome.php ├── Console └── Commands │ ├── CreateFilter.php │ ├── CreatePage.php │ ├── CreateResource.php │ ├── Install.php │ └── stubs │ └── resource.stub ├── Facades └── Front.php ├── Filters └── Filter.php ├── Front.php ├── FrontServiceProvider.php ├── Helpers ├── Actions.php └── PartialIndex.php ├── Http ├── Controllers │ ├── Controller.php │ ├── FrontController.php │ ├── PageController.php │ └── ToolsController.php └── helpers.php ├── Inputs ├── Autocomplete.php ├── BelongsTo.php ├── BelongsToMany.php ├── Boolean.php ├── Check.php ├── Checkboxes.php ├── Code.php ├── Date.php ├── DateTime.php ├── Disabled.php ├── File.php ├── HasMany.php ├── HasOneThrough.php ├── Hidden.php ├── ID.php ├── Image.php ├── ImageCropper.php ├── ImagePointer.php ├── Images.php ├── Input.php ├── InputGroup.php ├── Money.php ├── MorphMany.php ├── MorphTo.php ├── MorphToMany.php ├── Number.php ├── Password.php ├── Percentage.php ├── Select.php ├── Text.php ├── Textarea.php ├── Time.php └── Trix.php ├── Jobs ├── ActionShow.php ├── ActionStore.php ├── FrontDestroy.php ├── FrontIndex.php ├── FrontSearch.php ├── FrontShow.php ├── FrontStore.php ├── FrontUpdate.php ├── MassiveEditShow.php ├── MassiveEditStore.php ├── MassiveIndexEditShow.php └── MassiveIndexEditStore.php ├── Massives └── Massive.php ├── Pages └── Page.php ├── Resource.php ├── SecurityProvider.php ├── Texts ├── Alert.php ├── Button.php ├── Heading.php ├── HorizontalDescription.php ├── Paragraph.php ├── Table.php ├── Text.php └── Title.php ├── ThumbManager.php ├── Traits ├── HasActions.php ├── HasBreadcrumbs.php ├── HasCards.php ├── HasFilters.php ├── HasInputs.php ├── HasLenses.php ├── HasLinks.php ├── HasMassiveEditions.php ├── HasPermissions.php ├── InputRelationship.php ├── InputRules.php ├── InputSetters.php ├── InputVisibility.php ├── InputWithActions.php ├── InputWithLinks.php ├── IsALense.php ├── IsRunable.php ├── IsValidated.php ├── ResourceHelpers.php ├── Sourceable.php └── WithWidth.php └── Workers ├── FrontStore.php └── Worker.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | *.bak 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weblabormx/laravel-front", 3 | "description": "Front is a administration panel for Laravel. It allows you to create CRUD easily in minutes. It allows to fully customize any part of the code.", 4 | "keywords": [ 5 | "laravel", 6 | "admin" 7 | ], 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "Carlos Escobar", 12 | "email": "carlosescobar@weblabor.mx" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=7.1.0", 17 | "intervention/image": "^2.5", 18 | "laracasts/flash": ">=3", 19 | "laravel/framework": ">5.5", 20 | "opis/closure": "^3.1", 21 | "spatie/laravel-html": "^3.11", 22 | "weblabormx/file-modifier": "*" 23 | }, 24 | "autoload": { 25 | "files": [ 26 | "src/Http/helpers.php" 27 | ], 28 | "psr-4": { 29 | "WeblaborMx\\Front\\": "src/" 30 | } 31 | }, 32 | "extra": { 33 | "branch-alias": { 34 | "dev-master": "1.0.3-dev" 35 | }, 36 | "laravel": { 37 | "providers": [ 38 | "WeblaborMx\\Front\\FrontServiceProvider" 39 | ] 40 | } 41 | }, 42 | "config": { 43 | "sort-packages": true 44 | }, 45 | "minimum-stability": "dev", 46 | "prefer-stable": true 47 | } 48 | -------------------------------------------------------------------------------- /install-stubs/base-filter.php: -------------------------------------------------------------------------------- 1 | where('column', $value); 14 | } 15 | 16 | public function field() 17 | { 18 | return Text::make('Column'); 19 | } 20 | } -------------------------------------------------------------------------------- /install-stubs/page.php: -------------------------------------------------------------------------------- 1 | search($value); 14 | } 15 | 16 | public function field() 17 | { 18 | return Hidden::make('Search'); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /install-stubs/sidebar.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | @if( Gate::allows('viewAny', App\Page::class) ) 9 | 14 | @endif 15 | -------------------------------------------------------------------------------- /resources/lang/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "E-Mail Address": "Correo electrónico", 3 | "Password": "Contraseña", 4 | "Remember Me": "Recuérdame", 5 | "Login": "Acceder", 6 | "Forgot Your Password?": "¿Olvidaste tu contraseña?", 7 | "Register": "Registro", 8 | "Name": "Nombre", 9 | "Confirm Password": "Confirmar contraseña", 10 | "Reset Password": "Restablecer contraseña", 11 | "Reset Password Notification": "Aviso para restablecer contraseña", 12 | "You are receiving this email because we received a password reset request for your account.": "Estás recibiendo este email porque se ha solicitado un cambio de contraseña para tu cuenta.", 13 | "This password reset link will expire in :count minutes.": "Este enlace para restablecer la contraseña caduca en :count minutos.", 14 | "If you did not request a password reset, no further action is required.": "Si no has solicitado un cambio de contraseña, puedes ignorar o eliminar este e-mail.", 15 | "Please confirm your password before continuing.": "Por favor confirme su contraseña antes de continuar.", 16 | "Regards": "Saludos", 17 | "Whoops!": "¡Ups!", 18 | "Hello!": "¡Hola!", 19 | "If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "Si tienes problemas haciendo click en el botón \":actionText\", copia y pega el siguiente\nenlace en tu navegador: [:actionURL](:actionURL)", 20 | "Send Password Reset Link": "Enviar enlace para restablecer contraseña", 21 | "Logout": "Cerrar sesión", 22 | "Verify Email Address": "Confirmar correo electrónico", 23 | "Please click the button below to verify your email address.": "Por favor pulsa el siguiente botón para confirmar tu correo electrónico.", 24 | "If you did not create an account, no further action is required.": "Si no has creado ninguna cuenta, puedes ignorar o eliminar este e-mail.", 25 | "Verify Your Email Address": "Confirma tu correo electrónico", 26 | "A fresh verification link has been sent to your email address.": "Se ha enviado un nuevo enlace de verificación a tu correo electrónico.", 27 | "Before proceeding, please check your email for a verification link.": "Antes de poder continuar, por favor, confirma tu correo electrónico con el enlace que te hemos enviado.", 28 | "If you did not receive the email": "Si no has recibido el email", 29 | "click here to request another": "pulsa aquí para que te enviemos otro", 30 | "Welcome back": "Bienvenido", 31 | "Today is": "Hoy es", 32 | "Add": "Agregar", 33 | "Create": "Crear", 34 | "Edit": "Editar", 35 | "Delete": "Eliminar", 36 | "Yes": "Si", 37 | "No": "No", 38 | "Do you really want to remove this item?": "¿Quieres realmente remover este elemento?", 39 | "Actions": "Acciones", 40 | "Home": "Inicio", 41 | "See": "Ver", 42 | "Next errors were gotten:": "Los siguientes errores fueron encontrados:", 43 | "Save Changes": "Guardar cambios", 44 | "Add new": "Agregar nuevo", 45 | "FILTER :name": "FILTRAR :name", 46 | "Search": "Buscar", 47 | "No data to show": "Sin resultados encontrados", 48 | "See file": "Ver archivo", 49 | "Upload Image": "Subir imagen", 50 | "Save changes": "Guardar cambios", 51 | "Pick one..": "Seleccionar opción", 52 | ":name deleted successfully": ":name eliminado correctamente", 53 | ":name created successfully": ":name creado correctamente", 54 | ":name updated successfully": ":name editado correctamente", 55 | ":name action executed successfully": ":name ejecutado correctamente", 56 | "New rows": "Nuevas filas", 57 | "Options": "Opciones" 58 | } -------------------------------------------------------------------------------- /resources/views/cards/numeric.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | @if(!is_null($card->getIcon())) 4 | @if(!is_null($card->link())) 5 | 6 | @endif 7 | 8 | @if(!is_null($card->link())) 9 | 10 | @endif 11 | @endif 12 | 13 | 14 | {!! $card->showNumber($card->getNumber()) !!} 15 | {!! __($card->getSubtitle()) !!} 16 |
17 | 18 | @if($card->getPorcentage() > 0) 19 | {{$card->getPorcentage()}}% Increase 20 | @elseif($card->getPorcentage() < 0) 21 | {{($card->getPorcentage())*-1}}% Decrease 22 | @endif 23 | 24 | {!! __($card->getText()) !!} 25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /resources/views/components/cards.blade.php: -------------------------------------------------------------------------------- 1 | @if(count($cards)>0) 2 |
3 |
4 |
5 |
6 | @foreach($cards as $card) 7 | {!! $card->html() !!} 8 | @endforeach 9 |
10 |
11 |
12 |
13 | @endif -------------------------------------------------------------------------------- /resources/views/components/line.blade.php: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /resources/views/components/panel-form.blade.php: -------------------------------------------------------------------------------- 1 |
2 | @if(isset($panel->title) && strlen($panel->title) > 0) 3 |
4 |
5 |

@lang($panel->title ?: 'Basic Information')

6 |

{{$panel->description}}

7 |
8 |
9 |
10 | @else 11 |
12 | @endif 13 |
14 |
15 | @foreach($panel->fields()->where('needs_to_be_on_panel', true) as $field) 16 | {!! $field->formHtml() !!} 17 | @endforeach 18 |
19 |
20 | @if(isset($panel->title) && strlen($panel->title) > 0) 21 |
22 |
23 |
24 | @else 25 |
26 | @endif 27 | 28 | 33 |
-------------------------------------------------------------------------------- /resources/views/components/panel.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | @if(count($panel->actions)>0) 5 | @foreach($panel->actions as $action) 6 | {!! $action->button_text !!} 7 | @endforeach 8 | @endif 9 | @if(count($panel->links)>0) 10 | @foreach($panel->links as $link => $title) 11 | {!! $title !!} 12 | @endforeach 13 | @endif 14 |

@lang($panel->title ?: 'Basic Information')

15 |
16 |
17 |
18 | @foreach($panel->fields() as $field) 19 | {!! $field->showHtml($object) !!} 20 | @endforeach 21 |
22 |
23 |
24 |
-------------------------------------------------------------------------------- /resources/views/components/welcome.blade.php: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 | {{ __('Welcome back') }}, {{Auth::user()->name}}! 5 |
{{ __('Today is') }} {{now()->format($component->date_format)}}
6 |
7 |

8 | -------------------------------------------------------------------------------- /resources/views/crud/action.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('content') 4 | 5 | @include('front::elements.breadcrumbs', ['data' => ['action' => $action]]) 6 | @include('front::elements.errors') 7 | 8 |
9 |
10 |

{{ $action->title }}

11 |
12 |
13 | @foreach($action->buttons() as $link => $button) 14 | {!! $button !!} 15 | @endforeach 16 |
17 |
18 | 19 | {{ html()->form('POST', request()->url())->acceptsFiles()->open() }} 20 | 21 | @foreach($action->createPanels() as $panel) 22 | {!! $panel->formHtml() !!} 23 | @endforeach 24 | 25 | @if($action->hasHandle()) 26 |
27 | 28 |
29 | @endif 30 | 31 | {{ html()->form()->close() }} 32 | 33 | @stop 34 | -------------------------------------------------------------------------------- /resources/views/crud/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('content') 4 | 5 | @include('front::elements.breadcrumbs') 6 | @include ('front::elements.errors') 7 | 8 |

{{ __('Create') }} {{$front->label}}

9 | 10 | @include ('front::crud.partial-create', ['front' => $front]) 11 | 12 | @stop -------------------------------------------------------------------------------- /resources/views/crud/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('content') 4 | 5 | @include('front::elements.breadcrumbs') 6 | @include ('front::elements.errors') 7 | 8 | {{ html()->modelForm($object, 'PUT', $front->getBaseUrl() . '/' . $object->getKey())->acceptsFiles()->open() }} 9 | 10 |
11 |
12 |

{{ __('Edit') }} {{$front->getTitle($object)}}

13 |
14 |
15 | @if( $front->canRemove($object) ) 16 | {!! \Front::buttons()->getByName('delete', $front, $object)->form() !!} 17 | @endif 18 | 24 |
25 |
26 | 27 | {{ html()->hidden('redirect_url') }} 28 | @foreach($front->editPanels() as $panel) 29 | {!! $panel->formHtml() !!} 30 | @endforeach 31 | 32 | {{ html()->closeModelForm() }} 33 | 34 | @stop 35 | -------------------------------------------------------------------------------- /resources/views/crud/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('content') 4 | 5 | 6 | @include('front::elements.breadcrumbs') 7 | 8 |
9 |
10 |

{{$front->plural_label}}

11 |
12 |
13 | @foreach($front->getIndexLinks() as $button) 14 | {!! $button->form() !!} 15 | @endforeach 16 |
17 |
18 | 19 | @if(count($front->filters())>0) 20 |
{{ __('FILTER RESULTS', ['name' => strtoupper($front->plural_label)]) }}
21 | {{ html()->formWithDefaults(request()->all(), 'GET', request()->url())->open() }} 22 |
23 | {{ html()->hidden($front->getCurrentViewRequestName()) }} 24 | @foreach($front->getFilters() as $filter) 25 | {!! $filter->formHtml() !!} 26 | @endforeach 27 |
28 | {{ html()->submit(__('Search'))->class('bg-primary-600 text-white px-4 rounded mt-6 py-2 cursor-pointer') }} 29 |
30 |
31 | {{ html()->closeFormWithDefaults() }} 32 | @endif 33 | 34 | @if($front->getLenses()->count() > 1) 35 |
36 |

Lenses

37 | @foreach($front->getLenses() as $button) 38 | {!! $button->form() !!} 39 | @endforeach 40 |
41 | @endif 42 | 43 | @include ('front::components.cards', ['cards' => $front->cards()]) 44 | @include ($front->getCurrentView()) 45 | 46 | @endsection 47 | 48 | -------------------------------------------------------------------------------- /resources/views/crud/massive-edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('sidebar') 4 | 5 | @if (count($front->filters()) > 0) 6 |
{{ __('Options') }}
7 | {{ html()->form('GET', request()->url())->open() }} 8 |
9 | @foreach ($input->getMassiveForms() as $form) 10 | {!! $form->formHtml() !!} 11 | @endforeach 12 |
13 | {{ html()->submit(__('Search'))->class('btn btn-secondary btn-sm btn-block') }} 14 | {{ html()->form()->close() }} 15 | @endif 16 | 17 | @endsection 18 | 19 | @section('content') 20 | @include('front::elements.breadcrumbs', ['data' => ['massive' => $input]]) 21 | @include ('front::elements.errors') 22 | 23 | 24 |

{{ __('Edit') }} {{ $input->title }}

25 | 26 | {{ html()->form('POST', request()->url())->acceptsFiles()->open() }} 27 | 28 |
29 | 30 | 31 | 32 | @foreach ($input->getTableHeadings($object) as $title) 33 | 34 | @endforeach 35 | 36 | 37 | 38 | @foreach ($result as $object) 39 | 40 | @foreach ($input->getTableValues($object) as $value) 41 | 42 | @endforeach 43 | 44 | @endforeach 45 | @foreach ($input->getExtraTableValues() as $row) 46 | 47 | @foreach ($row as $value) 48 | 49 | @endforeach 50 | 51 | @endforeach 52 | 53 |
{{ $title }}
{!! $value !!}
{!! $value !!}
54 |
55 | @foreach (request()->except('rows') as $key => $value) 56 | {{ html()->hidden($key) }} 57 | @endforeach 58 | 59 |
60 | @foreach ($input->getTableButtons() as $name => $title) 61 | 62 | @endforeach 63 |
64 | 65 | {{ html()->form()->close() }} 66 | @endsection 67 | -------------------------------------------------------------------------------- /resources/views/crud/massive-index-edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('sidebar') 4 | 5 | @if (count($front->filters()) > 0) 6 |
{{ __('Options') }}
7 | 8 | {{ html()->form('GET', request()->url())->open() }} 9 |
10 | @foreach ($front->getMassiveForms() as $form) 11 | {!! $form->formHtml() !!} 12 | @endforeach 13 |
14 | {{ html()->submit(__('Search'))->class('btn btn-secondary btn-sm btn-block') }} 15 | {{ html()->form()->close() }} 16 | @endif 17 | 18 | @endsection 19 | 20 | @section('content') 21 | @include('front::elements.breadcrumbs', ['data' => ['massive' => $front]]) 22 | @include ('front::elements.errors') 23 | 24 | 25 |

{{ __('Edit') }} {{ $front->plural_label }}

26 | 27 | {{ html()->form('POST', request()->url())->acceptsFiles()->open() }} 28 | 29 |
30 | 31 | 32 | 33 | @foreach ($front->getTableHeadings() as $title) 34 | 35 | @endforeach 36 | 37 | 38 | 39 | @foreach ($result as $object) 40 | 41 | @foreach ($front->getTableValues($object) as $value) 42 | 43 | @endforeach 44 | 45 | @endforeach 46 | @foreach ($front->getExtraTableValues() as $row) 47 | 48 | @foreach ($row as $value) 49 | 50 | @endforeach 51 | 52 | @endforeach 53 | 54 |
{{ $title }}
{!! $value !!}
{!! $value !!}
55 |
56 | @foreach (request()->except('rows') as $key => $value) 57 | {{ html()->hidden($key) }} 58 | @endforeach 59 | 60 |
61 | @foreach ($front->getTableButtons() as $name => $title) 62 | 63 | @endforeach 64 |
65 | 66 | {{ html()->form()->close() }} 67 | @endsection 68 | -------------------------------------------------------------------------------- /resources/views/crud/partial-create.blade.php: -------------------------------------------------------------------------------- 1 | {{ html()->form('POST', $front->getBaseUrl())->acceptsFiles()->open() }} 2 | 3 | {{ html()->hidden('redirect_url') }} 4 | @foreach ($front->createPanels() as $panel) 5 | {!! $panel->formHtml() !!} 6 | @endforeach 7 |
8 | 14 |
15 | 16 | {{ html()->form()->close() }} 17 | -------------------------------------------------------------------------------- /resources/views/crud/partial-index.blade.php: -------------------------------------------------------------------------------- 1 | @php $helper = $front->getPartialIndexHelper($result, $pagination_name ?? null, $show_filters ?? null); @endphp 2 | 3 | @if ($result->count() > 0) 4 |
5 | {{ $helper->views() }} 6 | {{ $helper->totals() }} 7 | {{ $helper->filters() }} 8 |
9 |
10 | 11 | 12 | 13 | @foreach ($helper->headers() as $field) 14 | 15 | @endforeach 16 | @if ($helper->show_actions) 17 | 20 | @endif 21 | 22 | 23 | 24 | @foreach ($helper->rows() as $row) 25 | 26 | @foreach ($row->columns as $field) 27 | 30 | @endforeach 31 | @if ($helper->show_actions) 32 | @include('front::elements.object_actions', ['base_url' => $front->getBaseUrl(), 'object' => $row->object]) 33 | @endif 34 | 35 | @endforeach 36 | 37 |
{{ $field->title }} 18 | @lang('Edit') 19 |
28 | {!! $field->value !!} 29 |
38 |
39 |
40 | {{ $helper->views() }} 41 | {{ $helper->totals() }} 42 | {{ $helper->filters() }} 43 |
44 | @if($helper->links()!==null && $helper->links()->paginator->hasPages()) 45 |
46 | {{ $helper->links() }} 47 |
48 | @endif 49 | @else 50 |
51 | {{ __('No data to show') }} 52 |
53 | @endif 54 | -------------------------------------------------------------------------------- /resources/views/crud/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('content') 4 | @include('front::elements.breadcrumbs') 5 | 6 |
7 |
8 |

9 | {!! $front->getTitle($object) !!}

10 |
11 |
12 | @foreach ($front->getLinks($object) as $button) 13 | {!! $button->form() !!} 14 | @endforeach 15 |
16 |
17 | 18 |
19 | @foreach ($front->showPanels() as $panel) 20 | {!! $panel->showHtml($object) !!} 21 | @endforeach 22 | 23 | @php 24 | $porcentage = 0; 25 | @endphp 26 | 27 | @foreach ($front->showRelations() as $key => $relation) 28 | @php $porcentage += $relation->width_porcentage(); @endphp 29 |
30 |
31 |

32 |
{{ $relation->title }}
33 |
34 | @foreach ($relation->getLinks($object, $key, $front) as $button) 35 | {!! $button->form() !!} 36 | @endforeach 37 |
38 |

39 | {!! $relation->getValue($object) !!} 40 |
41 |
42 | @if ($porcentage >= 100) 43 | @php $porcentage = 0; @endphp 44 |
45 | @endif 46 | @endforeach 47 |
48 | 49 | @if (method_exists($object, 'getActivitylogOptions')) 50 | @include('front.timeline', ['object' => $object]) 51 | @endif 52 | @endsection 53 | -------------------------------------------------------------------------------- /resources/views/elements/breadcrumbs.blade.php: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /resources/views/elements/errors.blade.php: -------------------------------------------------------------------------------- 1 | @if($errors->any()) 2 |
3 | {{ __('Next errors were gotten:') }} {{ collect($errors->all())->implode(', ')}} 4 |
5 | @endif -------------------------------------------------------------------------------- /resources/views/elements/object_actions.blade.php: -------------------------------------------------------------------------------- 1 | @php $helper = $front->getActionsHelper($object, $base_url, $edit_link ?? null, $show_link ?? null); @endphp 2 | 3 | @if( $helper->isSortable() ) 4 | 5 | {!! \Front::buttons()->getByName('up')->addLink($helper->upUrl())->setType('')->setTitle('')->setClass('inline-block text-primary-600 hover:text-primary-800')->form() !!} 6 | {!! \Front::buttons()->getByName('down')->addLink($helper->downUrl())->setType('')->setTitle('')->setClass('inline-block text-primary-600 hover:text-primary-800')->form() !!} 7 | @endif 8 | @if( $helper->canShow() ) 9 | 10 | {!! \Front::buttons()->getByName('show')->addLink($helper->showUrl())->setType('')->setTitle('')->setClass('inline-block text-primary-600 hover:text-primary-800')->form() !!} 11 | @endif 12 | @if( $helper->canUpdate() ) 13 | 14 | {!! \Front::buttons()->getByName('edit')->addLink($helper->updateUrl())->setType('')->setTitle('')->setClass('inline-block text-primary-600 hover:text-primary-800')->form() !!} 15 | @endif 16 | 17 | @foreach($helper->getActions($object) as $action) 18 | 19 | @if(str_contains($action->icon, 'fa-')) 20 | 21 | @else 22 | 23 | @endif 24 | 25 | @endforeach 26 | @if( $helper->canRemove() ) 27 | 28 | {!! \Front::buttons()->getByName('delete', $front, $object)->setType('')->setTitle('')->setClass('inline-block text-red-400 hover:text-red-600')->form() !!} 29 | @endif 30 | 31 | -------------------------------------------------------------------------------- /resources/views/elements/relation_filters.blade.php: -------------------------------------------------------------------------------- 1 | {{ html()->form('GET', request()->url())->open() }} 2 | @foreach ($front->getFilters() as $filter) 3 | {!! $filter->formHtml() !!} 4 | @endforeach 5 | 6 | {{ html()->submit(__('Search')) }} 7 | {{ html()->form()->close() }} 8 | -------------------------------------------------------------------------------- /resources/views/elements/total_results.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{$total}} {{__('Results')}} 3 |
4 | -------------------------------------------------------------------------------- /resources/views/elements/views_buttons.blade.php: -------------------------------------------------------------------------------- 1 | @foreach($views as $view) 2 | 3 | @endforeach -------------------------------------------------------------------------------- /resources/views/input-form.blade.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | {!! $input->form() !!} 4 | @if(isset($input->help)) 5 | {!! $input->help !!} 6 | @endif 7 |
8 | -------------------------------------------------------------------------------- /resources/views/input-group.blade.php: -------------------------------------------------------------------------------- 1 |
2 | @isset($group->before) 3 | @foreach($group->before as $text) 4 | {{ $text }} 5 | @endforeach 6 | @endisset 7 | {!! $group->input !!} 8 | @isset($group->after) 9 | @foreach($group->after as $text) 10 | {{ $text }} 11 | @endforeach 12 | @endisset 13 |
14 | -------------------------------------------------------------------------------- /resources/views/input-outer.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {!! $value !!} 3 |
-------------------------------------------------------------------------------- /resources/views/input-show.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {!! $input->title !!} 3 |

{!! $input->getValueProcessed($object) !!}

4 |
5 | -------------------------------------------------------------------------------- /resources/views/inputs/file.blade.php: -------------------------------------------------------------------------------- 1 | {{ __('See file') }} -------------------------------------------------------------------------------- /resources/views/inputs/image-form.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | @php $column = $input->column; @endphp 4 | @if (isset($input->resource) && isset($input->resource->object) && isset($input->resource->object->$column)) 5 |

6 | @elseif(isset($input->value)) 7 |

8 | @endif 9 |

10 | 11 | {{ html()->hidden($input->column, $input->value) }} 12 | {{ html()->file($input->column . '_new')->style('display:none;') }} 13 |
14 |
15 | 16 | @pushonce('scripts-footer') 17 | 22 | @endpushonce 23 | @push('scripts-footer') 24 | 30 | @endpush 31 | -------------------------------------------------------------------------------- /resources/views/inputs/image.blade.php: -------------------------------------------------------------------------------- 1 | @isset($thumb) 2 | 3 | 4 | 5 | @endisset 6 | -------------------------------------------------------------------------------- /resources/views/inputs/images-form.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | {{ html()->file($input->column . '[]')->id($id)->style('display:none;')->multiple() }} 5 |
6 |
7 | 8 | @pushonce('scripts-footer') 9 | 14 | @endpushonce 15 | -------------------------------------------------------------------------------- /resources/views/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends((isset($front) && isset($front->layout)) ? $front->layout : ((isset($page) && isset($page->layout)) ? $page->layout : config('front.default_layout'))) 2 | 3 | @section('after-nav') 4 | 5 | 23 | 24 | @endsection 25 | 26 | @push('scripts-footer') 27 | 28 | @endpush 29 | -------------------------------------------------------------------------------- /resources/views/page.blade.php: -------------------------------------------------------------------------------- 1 | @extends('front::layout') 2 | 3 | @section('styles') 4 | @if (!is_null($page->style())) 5 | 8 | @endif 9 | @endsection 10 | 11 | @section('content') 12 | 13 | 14 | @component('front::elements.breadcrumbs') 15 | @foreach ($page->breadcrumbs() as $link => $title) 16 |
  • 17 | {{ $title }} 18 |
  • 19 | @endforeach 20 |
  • 21 | 22 | {{ $page->title }} 23 | 24 |
  • 25 | @endcomponent 26 | 27 | @if ($page->has_big_card) 28 |
    29 |
    30 |

    {{ $page->title }} 31 | @foreach ($page->getLinks() as $button) 32 | {!! $button->form() !!} 33 | @endforeach 34 |

    35 |
    36 |
    37 | @foreach ($page->allFields() as $field) 38 | {!! $field->html() !!} 39 | @endforeach 40 |
    41 |
    42 |
    43 | @else 44 |
    45 | @foreach ($page->allFields() as $field) 46 | {!! $field->html() !!} 47 | @endforeach 48 |
    49 | @endif 50 | 51 | @endsection 52 | -------------------------------------------------------------------------------- /resources/views/partials/user-navbar.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/texts/alert.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | {!! $alert->title !!}: {!! $alert->text !!} 3 |
    -------------------------------------------------------------------------------- /resources/views/texts/button.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | if($button->type=='btn-primary') { 3 | $classes = "ml-3 inline-flex items-center rounded-md border border-transparent bg-primary-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2"; 4 | } else if($button->type=='btn-secondary') { 5 | $classes = "ml-3 inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"; 6 | } else if($button->type=='btn-danger') { 7 | $classes = "ml-3 inline-flex items-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"; 8 | } else if($button->type=='btn-outline-danger') { 9 | $classes = "ml-3 inline-flex items-center rounded-md border border-transparent text-red-600 px-4 py-2 text-sm font-medium bg-white shadow-sm hover:text-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 border border-red-700"; 10 | } 11 | @endphp 12 | extra !!}> 13 | {!! $button->text !!} 14 | -------------------------------------------------------------------------------- /resources/views/texts/heading.blade.php: -------------------------------------------------------------------------------- 1 |
    2 |
    {{$heading->title}}
    3 |
    4 | -------------------------------------------------------------------------------- /resources/views/texts/horizontal-description.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | @foreach($horizontal_description->data as $title => $value) 3 |
    {!! $title !!}
    4 |
    {!! $value !!}
    5 | @endforeach 6 |
    -------------------------------------------------------------------------------- /resources/views/texts/paragraph.blade.php: -------------------------------------------------------------------------------- 1 |

    {!! $paragraph->title !!}

    -------------------------------------------------------------------------------- /resources/views/texts/table.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @foreach($table->headers as $header) 5 | 6 | @endforeach 7 | 8 | 9 | 10 | @foreach($table->data as $column) 11 | 12 | @foreach($column as $value) 13 | 14 | @endforeach 15 | 16 | @endforeach 17 | 18 |
    {!! $header !!}
    {!! $value !!}
    -------------------------------------------------------------------------------- /resources/views/texts/title.blade.php: -------------------------------------------------------------------------------- 1 | size}} class="mb-4">{{$component->title}}size}}> 2 | -------------------------------------------------------------------------------- /src/Actions/Action.php: -------------------------------------------------------------------------------- 1 | title)) { 24 | $title = Str::snake(class_basename(get_class($this))); 25 | $title = ucwords(str_replace('_', ' ', $title)); 26 | $this->title = $title; 27 | } 28 | if (is_null($this->slug)) { 29 | $this->slug = Str::slug(Str::snake(class_basename(get_class($this)))); 30 | } 31 | if (is_null($this->save_button)) { 32 | $this->save_button = __('Save changes'); 33 | } 34 | $this->title = __($this->title); 35 | $this->button_text = $this->getIconHtml()." $this->title"; 36 | } 37 | 38 | private function getIconHtml() 39 | { 40 | if(Str::contains($this->icon, '<')) { 41 | return $this->icon; 42 | } else if (Str::contains($this->icon, 'fa')) { 43 | return ""; 44 | } 45 | $data = [ 46 | 'name' => $this->icon, // Reemplaza con el nombre del icono 47 | 'class' => 'w-6 h-6 pr-2', 48 | ]; 49 | return Blade::render('', $data); 50 | } 51 | 52 | public function load() 53 | { 54 | // 55 | } 56 | 57 | public function addData($data) 58 | { 59 | $this->data = $data; 60 | $this->load(); 61 | return $this; 62 | } 63 | 64 | public function buttons() 65 | { 66 | return []; 67 | } 68 | 69 | public function fields() 70 | { 71 | return []; 72 | } 73 | 74 | public function hasPermissions($object) 75 | { 76 | return true; 77 | } 78 | 79 | public function validate($data) 80 | { 81 | $this->makeValidation($data); 82 | return $this; 83 | } 84 | 85 | public function getFieldsWithPanel() 86 | { 87 | $fields = collect($this->fields()); 88 | $components = $fields->filter(function ($item) { 89 | return class_basename(get_class($item)) == 'Panel'; 90 | })->filter(function ($item) { 91 | return $item->fields()->count() > 0; 92 | }); 93 | $fields = $fields->filter(function ($item) { 94 | return class_basename(get_class($item)) != 'Panel'; 95 | }); 96 | if ($fields->count() > 0) { 97 | $components[-1] = Panel::make('', $fields); 98 | } 99 | return $components->sortKeys()->values(); 100 | } 101 | 102 | public function show($result) 103 | { 104 | if (!is_string($result) && is_callable($result)) { 105 | $result = $result(); 106 | } 107 | $this->show = $result; 108 | return $this; 109 | } 110 | 111 | public function setObject($object) 112 | { 113 | $this->object = $object; 114 | return $this; 115 | } 116 | 117 | public function setTitle($title) 118 | { 119 | if (is_null($title)) { 120 | return $this; 121 | } 122 | $this->title = $title; 123 | $this->title = __($this->title); 124 | $this->button_text = $this->getIconHtml()." $this->title"; 125 | return $this; 126 | } 127 | 128 | public function setSlug($slug) 129 | { 130 | if (is_null($slug)) { 131 | return $this; 132 | } 133 | $this->slug = $slug; 134 | return $this; 135 | } 136 | 137 | public function setIcon($icon) 138 | { 139 | if (is_null($icon)) { 140 | return $this; 141 | } 142 | $this->icon = $icon; 143 | $this->button_text = $this->getIconHtml()." $this->title"; 144 | return $this; 145 | } 146 | 147 | public function showButton($show = true) 148 | { 149 | $this->show_button = $show; 150 | return $this; 151 | } 152 | 153 | public function getStyle() 154 | { 155 | if (isset($this->color)) { 156 | return 'background: '.$this->color; 157 | } 158 | return ''; 159 | } 160 | 161 | public function __get($name) 162 | { 163 | if (isset($this->object) && isset($this->object->$name)) { 164 | return $this->object->$name; 165 | } 166 | } 167 | 168 | public function __isset($name) 169 | { 170 | if (isset($this->object) && isset($this->object->$name)) { 171 | return $this->object->$name; 172 | } 173 | } 174 | 175 | public function setFront($front) 176 | { 177 | $this->front = $front; 178 | return $this; 179 | } 180 | 181 | public function results() 182 | { 183 | $result = $this->front->globalIndexQuery()->get(); 184 | $front_index = new FrontIndex($this->front, null); 185 | return $front_index->result($result); 186 | } 187 | 188 | public function hasHandle() 189 | { 190 | return method_exists($this, 'handle'); 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /src/ButtonManager.php: -------------------------------------------------------------------------------- 1 | getBaseUrl() . '/' . $object->getKey()) . "' data-redirection='" . url($front->getBaseUrl()) . "' data-variables='{ \"_method\": \"delete\", \"_token\": \"" . csrf_token() . "\" }'"; 17 | } 18 | 19 | return Button::make($config['name']) 20 | ->setIcon($config['icon']) 21 | ->setExtra($extra) 22 | ->setType($config['type']) 23 | ->setClass($config['class']); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Cards/Card.php: -------------------------------------------------------------------------------- 1 | fields)) { 19 | return; 20 | } 21 | $this->functions = collect($this->fields)->map(function ($item) { 22 | return [ 23 | 'get'.ucfirst($item), 24 | 'set'.ucfirst($item), 25 | ]; 26 | })->flatten(); 27 | $this->load(); 28 | } 29 | 30 | /* 31 | * Functions 32 | */ 33 | 34 | public function view() 35 | { 36 | $card = $this; 37 | return view($this->view, compact('card')); 38 | } 39 | 40 | public function html() 41 | { 42 | return $this->view()->render(); 43 | } 44 | 45 | public function load() 46 | { 47 | return; 48 | } 49 | 50 | /* 51 | * Magic Functions 52 | */ 53 | 54 | public function getter($name) 55 | { 56 | if (method_exists($this, $name)) { 57 | return $this->$name(); 58 | } 59 | if (isset($this->$name)) { 60 | return $this->$name; 61 | } 62 | return $this->data[$name] ?? null; 63 | } 64 | 65 | public function setter($name, $value) 66 | { 67 | $this->data[$name] = $value; 68 | return $this; 69 | } 70 | 71 | public function __call($method, $arguments) 72 | { 73 | if (!isset($this->functions) || !$this->functions->contains($method)) { 74 | throw new BadMethodCallException('The method '.get_class($this).'::'.$method.' can\'t be chained'); 75 | } 76 | if (Str::startsWith($method, 'get')) { 77 | $name = strtolower(str_replace('get', '', $method)); 78 | return $this->getter($name); 79 | } 80 | if (Str::startsWith($method, 'set')) { 81 | $name = strtolower(str_replace('set', '', $method)); 82 | return $this->setter($name, $arguments[0]); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Cards/NumericCard.php: -------------------------------------------------------------------------------- 1 | addMinutes(5); 34 | } 35 | 36 | public function showNumber($number) 37 | { 38 | return $number; 39 | } 40 | 41 | public function cacheName() 42 | { 43 | $name = get_class($this); 44 | return 'Card:'.$name; 45 | } 46 | 47 | public function getStyle() 48 | { 49 | $style = $this->style ?? ''; 50 | if (isset($this->background)) { 51 | $style .= ' background: '.$this->background; 52 | } 53 | return $style; 54 | } 55 | 56 | /* 57 | * Functions 58 | */ 59 | 60 | public function load() 61 | { 62 | 63 | $values = Cache::remember($this->cacheName(), $this->cacheFor() ?? 0, function () { 64 | return [ 65 | 'number' => $this->value(), 66 | 'porcentage' => $this->calculatePorcentage($this->value(), $this->old()) 67 | ]; 68 | }); 69 | $this->number = $values['number']; 70 | $this->porcentage = $values['porcentage']; 71 | } 72 | 73 | public function calculatePorcentage($now, $before) 74 | { 75 | if ($before == 0) { 76 | return 0; 77 | } 78 | $diff = $now - $before; 79 | return round(($diff / $before) * 100, 0); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Components/Component.php: -------------------------------------------------------------------------------- 1 | form(); 17 | } 18 | 19 | public function showHtml($object) 20 | { 21 | return $this->form(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Components/FrontCreate.php: -------------------------------------------------------------------------------- 1 | source = $source; 17 | $this->front_class = Front::makeResource($front_class, $this->source); 18 | $this->show_before = $this->front_class->canCreate(); 19 | } 20 | 21 | public function form() 22 | { 23 | $front = $this->front_class; 24 | if (isset($this->lense)) { 25 | $front = $front->getLense($this->lense); 26 | } 27 | if (isset($this->base_url)) { 28 | $front = $front->setBaseUrl($this->base_url); 29 | } 30 | return view('front::crud.partial-create', compact('front'))->render(); 31 | } 32 | 33 | public function setLense($lense) 34 | { 35 | $this->lense = $lense; 36 | return $this; 37 | } 38 | 39 | public function formUrl($base_url) 40 | { 41 | $this->base_url = $base_url; 42 | return $this; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Components/FrontIndex.php: -------------------------------------------------------------------------------- 1 | source = $source; 16 | $this->front_class = Front::makeResource($front_class, $this->source); 17 | $this->show_before = $this->front_class->canIndex(); 18 | } 19 | 20 | public function form() 21 | { 22 | $front = $this->front_class; 23 | if (isset($this->lense)) { 24 | $front = $front->getLense($this->lense); 25 | } 26 | $query = $front->globalIndexQuery(); 27 | if (isset($this->query)) { 28 | $function = $this->query; 29 | $query = $function($query); 30 | } 31 | $result = $query->get(); 32 | $style = 'margin-bottom: 30px;'; 33 | return view('front::crud.partial-index', compact('result', 'front', 'style'))->render(); 34 | } 35 | 36 | public function setRequest($request) 37 | { 38 | request()->request->add($request); 39 | return $this; 40 | } 41 | 42 | public function query($query) 43 | { 44 | $this->query = $query; 45 | return $this; 46 | } 47 | 48 | public function setLense($lense) 49 | { 50 | $this->lense = $lense; 51 | return $this; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Components/HtmlableComponent.php: -------------------------------------------------------------------------------- 1 | htmlable = $htmlable; 23 | 24 | parent::__construct(); 25 | } 26 | 27 | public function form() 28 | { 29 | return $this->htmlable->toHtml(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Components/Line.php: -------------------------------------------------------------------------------- 1 | render(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Components/Panel.php: -------------------------------------------------------------------------------- 1 | show_before = count($this->fields()) > 0; 20 | } 21 | 22 | public function formHtml() 23 | { 24 | $panel = $this; 25 | return view('front::components.panel-form', compact('panel')); 26 | } 27 | 28 | public function showHtml($object) 29 | { 30 | $panel = $this; 31 | $field = $this->fields()->first(); 32 | $is_input = is_object($field) ? $field->is_input : false; 33 | return view('front::components.panel', compact('panel', 'object', 'is_input')); 34 | } 35 | 36 | public function html() 37 | { 38 | $input = $this; 39 | $value = $this->showHtml(null); 40 | return view('front::input-outer', compact('value', 'input'))->render(); 41 | } 42 | 43 | public function getValue($object) 44 | { 45 | return $this->fields()->map(function ($item) use ($object) { 46 | return $item->showHtml($object); 47 | })->implode(''); 48 | } 49 | 50 | public function form() 51 | { 52 | return $this->fields()->map(function ($item) { 53 | return $item->formHtml(); 54 | })->implode(''); 55 | } 56 | 57 | private function filterFields($where, $model = null) 58 | { 59 | $where = $where == 'update' ? 'edit' : $where; 60 | $where = $where == 'store' ? 'create' : $where; 61 | return collect($this->column)->filter(function ($item) { 62 | return isset($item); 63 | })->flatten()->map(function ($item) use ($model) { 64 | return $item->setDefaultValueFromAttributes($model); 65 | })->filter(function ($item) use ($where) { 66 | if (is_null($where)) { 67 | return true; 68 | } 69 | $field = 'show_on_' . $where; 70 | if (!isset($item->$field)) { 71 | return true; 72 | } 73 | return $item->$field && $item->shouldBeShown(); 74 | }); 75 | } 76 | 77 | public function fields($model = null) 78 | { 79 | return $this->filterFields($this->source, $model); 80 | } 81 | 82 | public function setDescription($description) 83 | { 84 | $this->description = $description; 85 | return $this; 86 | } 87 | 88 | public function processData($inputs) 89 | { 90 | // Get fields processing 91 | $fields = $this->filterFields(null); 92 | 93 | $fields->each(function ($item) use (&$inputs) { 94 | $inputs = $item->processData($inputs); 95 | }); 96 | return $inputs; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Components/ShowCards.php: -------------------------------------------------------------------------------- 1 | cards = $cards; 12 | } 13 | 14 | public function form() 15 | { 16 | $cards = $this->cards; 17 | return view('front::components.cards', compact('cards'))->render(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Components/View.php: -------------------------------------------------------------------------------- 1 | column, $this->with)->render(); 13 | } 14 | 15 | public function with($array) 16 | { 17 | $this->with = $array; 18 | return $this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Components/Welcome.php: -------------------------------------------------------------------------------- 1 | render(); 13 | } 14 | 15 | public function setDateFormat($format) 16 | { 17 | $this->date_format = $format; 18 | return $this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Console/Commands/CreateFilter.php: -------------------------------------------------------------------------------- 1 | argument('name'); 34 | 35 | // Create Front/Filters folder if doesnt exist 36 | if (! is_dir(app_path('Front/Filters'))) { 37 | mkdir(app_path('Front/Filters')); 38 | $this->line('Filters folder created: '); 39 | } 40 | 41 | // Create filter base 42 | $file_name = app_path('Front/Filters/Filter.php'); 43 | if (!FileModifier::file($file_name)->exists()) { 44 | copy($directory . '/base-filter.php', $file_name); 45 | $this->line('Base Filter class created: '); 46 | } 47 | 48 | // Create search filter base 49 | $file_name = app_path('Front/Filters/SearchFilter.php'); 50 | if (!FileModifier::file($file_name)->exists()) { 51 | copy($directory . '/search-filter.php', $file_name); 52 | $this->line('Search Filter added on filters folder: '); 53 | } 54 | 55 | // Create resource 56 | $file_name = app_path('Front/Filters/' . $name . '.php'); 57 | if (FileModifier::file($file_name)->exists()) { 58 | $this->line('Filter already exists.'); 59 | return; 60 | } 61 | copy($directory . '/filter.php', $file_name); 62 | 63 | FileModifier::file($file_name) 64 | ->replace('{name}', $name) 65 | ->replace('{slug}', Str::slug(Str::plural($name))) 66 | ->execute(); 67 | 68 | $this->line('Filter created: '); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Console/Commands/CreatePage.php: -------------------------------------------------------------------------------- 1 | argument('name'); 34 | 35 | // Create Front Folder if doesnt exist 36 | if (! is_dir(app_path('Front'))) { 37 | mkdir(app_path('Front')); 38 | } 39 | 40 | // Create Front/Page folder if doesnt exist 41 | if (! is_dir(app_path('Front/Pages'))) { 42 | mkdir(app_path('Front/Pages')); 43 | } 44 | 45 | // Create resource base 46 | $file_name = app_path('Front/Pages/Page.php'); 47 | if (!FileModifier::file($file_name)->exists()) { 48 | copy($directory . '/base-page.php', $file_name); 49 | } 50 | 51 | // Create resource 52 | $file_name = app_path('Front/Pages/' . $name . '.php'); 53 | if (FileModifier::file($file_name)->exists()) { 54 | $this->line('Page already exists.'); 55 | return; 56 | } 57 | copy($directory . '/page.php', $file_name); 58 | 59 | FileModifier::file($file_name) 60 | ->replace('{name}', $name) 61 | ->replace('{slug}', Str::slug(Str::plural($name))) 62 | ->execute(); 63 | 64 | $this->line('Page created: '); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Console/Commands/CreateResource.php: -------------------------------------------------------------------------------- 1 | createFrontDir(); 36 | $this->createResourceParent(); 37 | 38 | $model = str($this->argument('model'))->replace('/', '\\'); 39 | 40 | $class = $model 41 | ->prepend(config('front.models_folder') . '\\') 42 | ->replace('App\\Models', '') 43 | ->replace('App\\', '\\') 44 | ->trim('/') 45 | ->trim('\\'); 46 | 47 | $classBasename = $class->classBasename(); 48 | $classVendor = $class->beforeLast("{$classBasename}")->trim('\\'); 49 | 50 | $filename = $classVendor 51 | ->replace('\\', '/') 52 | ->append("/{$classBasename}") 53 | ->append('.php') 54 | ->toString(); 55 | $filename = $this->resolveFrontDir($filename); 56 | 57 | $slug = $classBasename->snake()->plural(); 58 | 59 | if (is_file($filename)) { 60 | $this->error($class . ' already exists.'); 61 | return; 62 | } 63 | 64 | if ($this->option('all')) { 65 | $this->input->setOption('policy', true); 66 | $this->input->setOption('model', true); 67 | } 68 | 69 | if ($this->option('model')) { 70 | $this->call('make:model', ['name' => $class]); 71 | $this->call('make:migration', ['name' => "create_{$slug}_table"]); 72 | } 73 | 74 | if ($this->option('policy')) { 75 | $this->call('make:policy', [ 76 | 'name' => "{$classBasename}Policy", 77 | '--model' => $class 78 | ]); 79 | } 80 | 81 | $parent = config('front.resources_folder') . '\\Resource'; 82 | 83 | $namespace = collect([ 84 | config('front.resources_folder'), 85 | $classVendor->toString(), 86 | ])->filter()->implode('\\'); 87 | 88 | $url = $classVendor->lower() 89 | ->replace('\\', '/') 90 | ->append($slug) 91 | ->trim('/'); 92 | 93 | if (!is_dir($dirname = dirname($filename))) { 94 | mkdir($dirname, 0755, true); 95 | } 96 | 97 | copy($this->resolveStubPath('/resource.stub'), $filename); 98 | 99 | FileModifier::file($filename) 100 | ->replace('{{ model }}', "App\\Models\\$class") 101 | ->replace('{{ class }}', $classBasename) 102 | ->replace('{{ parent }}', $parent) 103 | ->replace('{{ default_base_url }}', rtrim(config('front.default_base_url'), '/')) 104 | ->replace('{{ url }}', $url) 105 | ->replace('{{ namespace }}', $namespace) 106 | ->execute(); 107 | 108 | $this->components->info(sprintf('Resource [%s] created successfully.', $this->prettifyPath($filename))); 109 | } 110 | 111 | protected function prettifyPath($path) 112 | { 113 | return str($path)->after(base_path())->trim('/'); 114 | } 115 | 116 | protected function resolveFrontDir($path = '') 117 | { 118 | $vendor = str(config('front.resources_folder')); 119 | return str(base_path( 120 | $vendor 121 | ->after('\\') 122 | ->prepend( 123 | $vendor->before('\\') 124 | ->snake() 125 | ->append('\\') 126 | ) 127 | ->replace('\\', '/') 128 | ))->append('/' . ltrim($path, '/')) 129 | ->rtrim('/') 130 | ->toString(); 131 | } 132 | 133 | protected function resolveStubPath($stub) 134 | { 135 | $stub = trim($stub, '/'); 136 | return file_exists($customPath = $this->laravel->basePath('/stubs/' . $stub)) 137 | ? $customPath 138 | : __DIR__ . '/stubs/' . $stub; 139 | } 140 | 141 | protected function createFrontDir() 142 | { 143 | $path = $this->resolveFrontDir(); 144 | 145 | if (!is_dir($path)) { 146 | mkdir($path, 0755, true); 147 | $this->components->info(sprintf('Folder [%s] created successfully.', $this->prettifyPath($path))); 148 | } 149 | } 150 | 151 | protected function createResourceParent() 152 | { 153 | $path = $this->resolveFrontDir('/Resource.php'); 154 | $directory = WLFRONT_PATH . '/install-stubs'; 155 | 156 | if (!FileModifier::file($path)->exists()) { 157 | copy($directory . '/base-resource.php', $path); 158 | $this->components->info(sprintf('Class [%s] created successfully.', $this->prettifyPath($path))); 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/Console/Commands/Install.php: -------------------------------------------------------------------------------- 1 | "WeblaborMx\Front\Facades\FrontServiceProvider", 35 | ]); 36 | $this->line('Configuration files published: '); 37 | 38 | $directory = WLFRONT_PATH . '/install-stubs'; 39 | 40 | // Create Front Folder on views if doesnt exist 41 | if (! is_dir(resource_path('views/front'))) { 42 | mkdir(resource_path('views/front')); 43 | } 44 | 45 | // Create Front Folder if doesnt exist 46 | if (! is_dir(app_path('Front'))) { 47 | mkdir(app_path('Front')); 48 | $this->line('Front folder created: '); 49 | } 50 | 51 | // Create Front/Filters folder if doesnt exist 52 | if (! is_dir(app_path('Front/Filters'))) { 53 | mkdir(app_path('Front/Filters')); 54 | $this->line('Filters folder created: '); 55 | } 56 | 57 | // Create filter base 58 | $file_name = app_path('Front/Filters/Filter.php'); 59 | if (!FileModifier::file($file_name)->exists()) { 60 | copy($directory . '/base-filter.php', $file_name); 61 | $this->line('Base Filter class created: '); 62 | } 63 | 64 | // Create search filter base 65 | $file_name = app_path('Front/Filters/SearchFilter.php'); 66 | if (!FileModifier::file($file_name)->exists()) { 67 | copy($directory . '/search-filter.php', $file_name); 68 | $this->line('Search Filter added on filters folder: '); 69 | } 70 | 71 | // Copy sidebar 72 | $file_name = resource_path('views/front/sidebar.blade.php'); 73 | if (FileModifier::file($file_name)->exists()) { 74 | $this->line('Sidebar already exists.'); 75 | } else { 76 | copy($directory . '/sidebar.blade.php', $file_name); 77 | $this->line('Sidebar added: '); 78 | } 79 | 80 | // Copy all files 81 | /*(new Filesystem)->copyDirectory( 82 | WLFRONT_PATH.'/install-stubs/public', public_path('') 83 | ); 84 | $this->line('Assets added: ');*/ 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Console/Commands/stubs/resource.stub: -------------------------------------------------------------------------------- 1 | ,class-string<\WeblaborMx\Front\Resource>> getRegisteredResources() 9 | * @method static \WeblaborMx\Front\Resource makeResource(string $resource, ?string $source = null) 10 | * @method static class-string<\WeblaborMx\Front\Resource> registerResource(string $resource) 11 | * @method static class-string<\WeblaborMx\Front\Resource> resolveResource(string $resource) 12 | * @method static class-string<\WeblaborMx\Front\Pages\Page> resolvePage(string $page) 13 | * @method static \WeblaborMx\Front\ButtonManager buttons() 14 | * @method static \WeblaborMx\Front\ThumbManager thumbs() 15 | * @method static string baseNamespace() 16 | * @method static \Illuminate\Routing\Route routeOf(class-string<\WeblaborMx\Front\Resource|\WeblaborMx\Front\Page>|\WeblaborMx\Front\Resource|\WeblaborMx\Front\Page $frontItem, string|null $action) 17 | * 18 | * @see \WeblaborMx\Front\Front 19 | */ 20 | class Front extends Facade 21 | { 22 | public static function getFacadeAccessor() 23 | { 24 | return \WeblaborMx\Front\Front::class; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Filters/Filter.php: -------------------------------------------------------------------------------- 1 | slug)) { 19 | $this->slug = Str::slug(Str::snake(class_basename(get_class($this))), '_'); 20 | } 21 | } 22 | 23 | /* 24 | * Needed functions 25 | */ 26 | 27 | public function default() 28 | { 29 | return $this->default; 30 | } 31 | 32 | public function apply($query, $value) 33 | { 34 | return $query; 35 | } 36 | 37 | public function field() 38 | { 39 | return; 40 | } 41 | 42 | /* 43 | * Hidden functions 44 | */ 45 | 46 | public function setResource($resource) 47 | { 48 | $this->resource = $resource; 49 | return $this; 50 | } 51 | 52 | public function formHtml() 53 | { 54 | $input = $this->field(); 55 | if (is_null($input)) { 56 | return; 57 | } 58 | return $input->setColumn($this->slug)->formHtml(); 59 | } 60 | 61 | public function setDefault($default) 62 | { 63 | $this->default = $default; 64 | return $this; 65 | } 66 | 67 | public function show($result) 68 | { 69 | if (!is_string($result) && is_callable($result)) { 70 | $result = $result(); 71 | } 72 | $this->show = $result; 73 | return $this; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Front.php: -------------------------------------------------------------------------------- 1 | ,class-string> */ 14 | private array $cachedResourceClasses = []; 15 | 16 | /** @var array,Route> */ 17 | private array $cachedRoutes = []; 18 | 19 | /* -------------------- 20 | * Helpers 21 | ---------------------- */ 22 | 23 | public function baseNamespace(): string 24 | { 25 | return trim(config('front.resources_folder'), '\\') . '\\'; 26 | } 27 | 28 | public function thumbs(): ThumbManager 29 | { 30 | return app(ThumbManager::class); 31 | } 32 | 33 | public function buttons(): ButtonManager 34 | { 35 | return app(ButtonManager::class); 36 | } 37 | 38 | /* -------------------- 39 | * Route registrar 40 | ---------------------- */ 41 | 42 | /** @var array,class-string> */ 43 | public function getRegisteredResources(): array 44 | { 45 | return $this->cachedResourceClasses; 46 | } 47 | 48 | public function makeResource(string $resource, ?string $source = null): Resource 49 | { 50 | $class = $this->resolveResource($resource); 51 | 52 | return new $class($source); 53 | } 54 | 55 | public function registerRoute(string|Resource|Page $frontItem, Route $route, string $action): Route 56 | { 57 | $key = is_object($frontItem) ? $frontItem::class : $frontItem; 58 | 59 | if (!isset($this->cachedRoutes[$key])) { 60 | $this->cachedRoutes[$key] = []; 61 | } 62 | 63 | $this->cachedRoutes[$key][$action] = $route; 64 | 65 | return $route; 66 | } 67 | 68 | public function routeOf(string|Resource|Page $frontItem, ?string $action = null): ?Route 69 | { 70 | if (is_object($frontItem)) { 71 | $key = $frontItem::class; 72 | $action = $action ?? $frontItem->source; 73 | } else { 74 | $key = $frontItem; 75 | $action = $action ?? 'index'; 76 | } 77 | 78 | if (!isset($this->cachedRoutes[$key])) { 79 | return null; 80 | } 81 | 82 | return $this->cachedRoutes[$key][$action] ?? null; 83 | } 84 | 85 | /** @return array, \Illuminate\Routing\Route> */ 86 | public function getRegisteredRoutes(): array 87 | { 88 | return $this->cachedRoutes; 89 | } 90 | 91 | /** @return class-string */ 92 | public function registerResource(string $resource): string 93 | { 94 | $resource = $this->resolveResource($resource); 95 | 96 | $this->cachedResourceClasses[$resource] = $resource; 97 | 98 | return $resource; 99 | } 100 | 101 | /** @return class-string */ 102 | public function resolveResource(string $resource): string 103 | { 104 | if (isset($this->cachedResourceClasses[$resource])) { 105 | return $resource; 106 | } 107 | 108 | if (\class_exists($resource)) { 109 | if (\is_subclass_of($resource, Resource::class)) { 110 | return $resource; 111 | } elseif (!\is_subclass_of($resource, Model::class)) { 112 | throw new \InvalidArgumentException("Class '{$resource}' cannot be resolved to a Front Resource"); 113 | } 114 | } 115 | 116 | $namespace = $this->baseNamespace(); 117 | $basename = str($resource) 118 | ->after($namespace) 119 | ->toString(); 120 | 121 | $found = \array_values(\array_filter( 122 | $this->cachedResourceClasses, 123 | fn($class) => \str_ends_with($class, $basename) 124 | )); 125 | 126 | if (empty($found)) { 127 | return $namespace . $basename; 128 | } 129 | 130 | return $found[0]; 131 | } 132 | 133 | /** @return class-string */ 134 | public function resolvePage(string $page): string 135 | { 136 | if (\class_exists($page)) { 137 | if (\is_subclass_of($page, Page::class)) { 138 | return $page; 139 | } 140 | 141 | throw new \InvalidArgumentException("Class '{$page}' cannot be resolved to a Front Page"); 142 | } 143 | 144 | return 'App\\Front\\Pages\\' . $page; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Helpers/Actions.php: -------------------------------------------------------------------------------- 1 | front = $front; 18 | $this->object = $object; 19 | $this->edit_link = $edit_link ?? '{key}/edit'; 20 | $this->show_link = $show_link; 21 | $this->base_url = $base_url; 22 | return $this; 23 | 24 | } 25 | 26 | public function canShow() 27 | { 28 | if (!$this->isEloquent()) { 29 | return false; 30 | } 31 | return $this->front->canShow($this->object); 32 | } 33 | 34 | public function canUpdate() 35 | { 36 | if (!$this->isEloquent()) { 37 | return false; 38 | } 39 | return $this->front->canUpdate($this->object); 40 | } 41 | 42 | public function canRemove() 43 | { 44 | if (!$this->isEloquent()) { 45 | return false; 46 | } 47 | return $this->front->canRemove($this->object); 48 | } 49 | 50 | public function showUrl() 51 | { 52 | $link = $this->base_url.'/'.$this->object->getKey(); 53 | return $link.$this->show_link; 54 | } 55 | 56 | public function updateUrl() 57 | { 58 | $edit = str_replace('{key}', $this->object->getKey(), $this->edit_link); 59 | $link = $this->base_url.'/'.$edit; 60 | return $link.$this->show_link; 61 | } 62 | 63 | public function removeUrl() 64 | { 65 | $link = $this->base_url.'/'.$this->object->getKey(); 66 | return $link; 67 | } 68 | 69 | public function upUrl() 70 | { 71 | $link = $this->base_url.'/'.$this->object->getKey().'/sortable/up'; 72 | return $link; 73 | } 74 | 75 | public function downUrl() 76 | { 77 | $link = $this->base_url.'/'.$this->object->getKey().'/sortable/down'; 78 | return $link; 79 | } 80 | 81 | private function isEloquent() 82 | { 83 | return is_subclass_of($this->object, 'Illuminate\Database\Eloquent\Model'); 84 | } 85 | 86 | public function isSortable() 87 | { 88 | return isset(class_uses($this->object)['Spatie\EloquentSortable\SortableTrait']); 89 | } 90 | 91 | public function getActions($object) 92 | { 93 | return $this->front->getActions()->where('show_on_index', 1)->filter(function ($item) use ($object) { 94 | return $item->hasPermissions($object); 95 | })->map(function ($item) use ($object) { 96 | $item->url = $this->front->getBaseUrl()."/{$object->getKey()}/action/{$item->slug}"; 97 | return $item; 98 | }); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | setSource('index'); 14 | if ($action != 'get') { 15 | $page = $page->changeFieldsFunction($action); 16 | } 17 | $method = 'execute' . ucfirst($action); 18 | return $page->$method(compact('page', 'action')); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Http/Controllers/ToolsController.php: -------------------------------------------------------------------------------- 1 | variables); 15 | $file = $request->file; 16 | 17 | $new_file = Intervention::make($file); 18 | if ($new_file->height() > $variables->height || $new_file->width() > $variables->width) { 19 | $new_file = $new_file->resize($variables->width, $variables->height, function ($constraint) { 20 | $constraint->aspectRatio(); 21 | }); 22 | } 23 | 24 | $new_name = $this->getFileName($file); 25 | $file_name = $variables->directory.'/'.$new_name; 26 | $storage_file = Storage::put($file_name, (string) $new_file->encode(), 'public'); 27 | $url = Storage::url($file_name); 28 | 29 | $response = new \StdClass(); 30 | $response->link = $url; 31 | return response(stripslashes(json_encode($response))); 32 | } 33 | 34 | private function getFileName($file) 35 | { 36 | $file_name = Str::random(9); 37 | if (is_string($file)) { 38 | $extension = explode('.', $file); 39 | $extension = $extension[count($extension) - 1]; 40 | } else { 41 | $extension = $file->guessExtension(); 42 | } 43 | $file_name .= '.'.$extension; 44 | return $file_name; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/Http/helpers.php: -------------------------------------------------------------------------------- 1 | getMorphClass(); 49 | $class = str_replace('App\\Models\\', '', $class); 50 | return getFront($class)->setObject($object); 51 | } 52 | 53 | function getButtonByName($name, $front = null, $object = null) 54 | { 55 | return (new Front)->buttons()->getByName($name, $front, $object); 56 | } 57 | 58 | function isResponse($response) 59 | { 60 | if (!is_object($response)) { 61 | return false; 62 | } 63 | $class = get_class($response); 64 | $classes = [$class]; 65 | while (true) { 66 | $class = get_parent_class($class); 67 | if (!$class) { 68 | break; 69 | } 70 | $classes[] = $class; 71 | } 72 | return collect($classes)->contains(function ($item) { 73 | return Str::contains($item, [ 74 | 'Symfony\Component\HttpFoundation\Response', 75 | 'Illuminate\View\View' 76 | ]); 77 | }); 78 | } 79 | 80 | function saveImagesWithThumbs($image, $directory, $file_name, $disk = null) 81 | { 82 | if (is_null($disk)) { 83 | $disk = config('front.disk', 'public'); 84 | } 85 | 86 | $thumbnails = config('front.thumbnails', []); 87 | Storage::putFileAs($directory, $image, $file_name); 88 | 89 | foreach ($thumbnails as $thumbnail) { 90 | $width = $thumbnail['width']; 91 | $height = $thumbnail['height']; 92 | $prefix = $thumbnail['prefix']; 93 | $is_fit = $thumbnail['fit'] ?? false; 94 | 95 | // Make smaller the image 96 | $new_file = Intervention::make($image); 97 | 98 | if ($is_fit) { 99 | $new_file = $new_file->fit($width, $height); 100 | } elseif ($new_file->height() > $height || $new_file->width() > $width) { 101 | $new_file = $new_file->resize($width, $height, function ($constraint) { 102 | $constraint->aspectRatio(); 103 | }); 104 | } 105 | 106 | // Save the image 107 | $new_name = getThumb($file_name, $prefix, true); 108 | $new_file_name = $directory . '/' . $new_name; 109 | Storage::put($new_file_name, (string) $new_file->encode(), 'public'); 110 | } 111 | return $directory . '/' . $file_name; 112 | } 113 | 114 | function deleteImagesWithThumbs($file_name, $disk = null) 115 | { 116 | if (is_null($disk)) { 117 | $disk = config('front.disk', 'public'); 118 | } 119 | 120 | $thumbnails = config('front.thumbnails', []); 121 | foreach ($thumbnails as $thumbnail) { 122 | $prefix = $thumbnail['prefix']; 123 | $new_name = getThumb($file_name, $prefix, true); 124 | if(!Storage::exists($new_name)) { 125 | continue; 126 | } 127 | Storage::delete($new_name); 128 | } 129 | if (!Storage::exists($file_name)) { 130 | return; 131 | } 132 | Storage::delete($file_name); 133 | } 134 | 135 | function getImageUrl($path, $default = null, $disk = null) 136 | { 137 | $disk = $disk ?? config('filesystems.default'); 138 | if (!$path || !Storage::disk($disk)->exists($path)) { 139 | return $default; 140 | } 141 | 142 | $publicDisks = collect(config('filesystems.disks'))->where('visibility', 'public')->keys()->all(); 143 | if (in_array($disk, $publicDisks)) { 144 | return Storage::disk($disk)->url($path); 145 | } 146 | 147 | $cacheKey = "temporary_url:{$disk}:{$path}"; 148 | return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($disk, $path) { 149 | return Storage::disk($disk)->temporaryUrl($path, now()->addMinutes(5)); 150 | }); 151 | } -------------------------------------------------------------------------------- /src/Inputs/Autocomplete.php: -------------------------------------------------------------------------------- 1 | attributes['data-type'] = 'autocomplete'; 13 | $this->attributes['src'] = $this->url; 14 | 15 | $value = isset($this->default_value) ? $this->default_value : html()->value($this->column); 16 | if (!is_null($value)) { 17 | $this->attributes['data-selected-value'] = $value; 18 | // Fill text 19 | if (isset($this->text)) { 20 | $this->attributes['data-selected-text'] = $this->text; 21 | } else { 22 | $value = html()->value($this->column . '_text'); 23 | $this->attributes['data-selected-text'] = $value; 24 | } 25 | } 26 | if ($this->source == 'create' || $this->source == 'edit') { 27 | $this->attributes['data-text-input'] = 'false'; 28 | } 29 | 30 | if (isset($this->attributes['disabled'])) { 31 | return html() 32 | ->text($this->column . '_hidden', $this->attributes['data-selected-text'] ?? false) 33 | ->attributes(['disabled' => 'disabled']); 34 | } 35 | 36 | return html() 37 | ->text($this->column, $this->default_value) 38 | ->attributes($this->attributes); 39 | } 40 | 41 | public function setUrl($url) 42 | { 43 | $this->url = url($url); 44 | return $this; 45 | } 46 | 47 | public function setText($text) 48 | { 49 | $this->text = $text; 50 | return $this; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Inputs/BelongsToMany.php: -------------------------------------------------------------------------------- 1 | model_name = $model_name; 19 | $this->relation = Str::snake(Str::plural($relation)); 20 | $this->source = $source; 21 | 22 | if (!isset($this->model_name)) { 23 | $front = Str::singular($this->relation); 24 | $front = ucfirst(Str::camel($front)); 25 | $this->model_name = $title; 26 | } 27 | 28 | $this->relation_front = Front::makeResource($this->model_name, $this->source); 29 | if (!$this->relation_front->canIndex()) { 30 | $this->show = false; 31 | } 32 | $class = $this->relation_front->getModel(); 33 | $this->title = $this->relation_front->label; 34 | $this->load(); 35 | } 36 | 37 | public function setResource($resource) 38 | { 39 | $relation = $this->relation; 40 | $this->column = $relation . '_mtm'; 41 | if (is_object($resource->object)) { 42 | $this->default_value = $resource->object->{$this->relation}->pluck('id'); 43 | $this->default_value_force = true; 44 | } 45 | 46 | return parent::setResource($resource); 47 | } 48 | 49 | public function getValue($object) 50 | { 51 | $relation = $this->relation; 52 | if (!is_object($object->$relation)) { 53 | return '--'; 54 | } 55 | 56 | $title_field = $this->search_field ?? $this->relation_front->title; 57 | $value = $object->$relation->pluck($title_field); 58 | 59 | if (strlen($value) <= 0) { 60 | return '--'; 61 | } 62 | 63 | $value = $value->map(function ($item) { 64 | return "
  • " . $item . "
  • "; 65 | }); 66 | return '
      ' . $value->implode('') . '
    '; 67 | } 68 | 69 | public function form() 70 | { 71 | $model = $this->relation_front->getModel(); 72 | $model = new $model; 73 | 74 | if (isset($this->force_query)) { 75 | $force_query = $this->force_query; 76 | $query = $force_query($model); 77 | } else { 78 | $query = $this->relation_front->globalIndexQuery(); 79 | } 80 | 81 | if (isset($this->filter_query)) { 82 | $filter_query = $this->filter_query; 83 | $query = $filter_query($query); 84 | } 85 | 86 | $options = $query->get(); 87 | if (isset($this->filter_collection)) { 88 | $filter_collection = $this->filter_collection; 89 | $options = $filter_collection($options); 90 | } 91 | 92 | $title = $this->search_field ?? $this->relation_front->search_title; 93 | $options = $options->pluck($title, $model->getKeyName()); 94 | $select = Select::make($this->title, $this->column) 95 | ->options($options) 96 | ->default($this->default_value, $this->default_value_force) 97 | ->size($this->size) 98 | ->setEmptyTitle($this->empty_title) 99 | ->withMeta($this->attributes) 100 | ->setPlaceholder($this->show_placeholder); 101 | if($this->is_multiple) { 102 | $select = $select->multiple(); 103 | } 104 | return $select->form(); 105 | } 106 | 107 | public function processDataAfterValidation($data) 108 | { 109 | unset($data[$this->column]); 110 | return $data; 111 | } 112 | 113 | public function processAfterSave($object, $request) 114 | { 115 | $values = $request->{$this->column}; 116 | $object->{$this->relation}()->sync($values); 117 | } 118 | 119 | public function setSearchField($field) 120 | { 121 | $this->search_field = $field; 122 | return $this; 123 | } 124 | 125 | public function setEmptyTitle($value) 126 | { 127 | $this->empty_title = $value; 128 | return $this; 129 | } 130 | 131 | public function hidePlaceholder() 132 | { 133 | $this->show_placeholder = false; 134 | return $this; 135 | } 136 | 137 | public function noMultiple() 138 | { 139 | $this->is_multiple = false; 140 | return $this; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Inputs/Boolean.php: -------------------------------------------------------------------------------- 1 | checkbox( 14 | $this->column, 15 | !is_null($this->default_value) ? $this->default_value == $this->true_value : null, 16 | $this->true_value 17 | ); 18 | } 19 | 20 | public function getValue($object) 21 | { 22 | $value = parent::getValue($object); 23 | $value = $value === '--' ? false : $value; 24 | if ($this->source == 'index') { 25 | if ($value) { 26 | return ''; 27 | } 28 | return ''; 29 | } 30 | if ($value == $this->true_value) { 31 | return ' ' . __('Yes'); 32 | } 33 | return ' ' . __('No'); 34 | } 35 | 36 | public function setTrueValue($value) 37 | { 38 | $this->true_value = $value; 39 | return $this; 40 | } 41 | 42 | public function setFalseValue($value) 43 | { 44 | $this->false_value = $value; 45 | return $this; 46 | } 47 | 48 | public function processData($data) 49 | { 50 | if (!isset($data[$this->column])) { 51 | $data[$this->column] = $this->false_value; 52 | } 53 | return $data; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Inputs/Check.php: -------------------------------------------------------------------------------- 1 | checkbox($this->column, $this->default_value) 11 | ->attributes($this->attributes); 12 | } 13 | 14 | public function getValue($object) 15 | { 16 | $column = $this->column; 17 | if (!is_string($column) && is_callable($column)) { 18 | $return = $column($object); 19 | } else { 20 | $return = $object->$column; 21 | } 22 | if ($return) { 23 | return ''; 24 | } 25 | return ''; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Inputs/Checkboxes.php: -------------------------------------------------------------------------------- 1 | map(function ($item) { 16 | return "
  • ".$item."
  • "; 17 | }); 18 | return '
      '.$return->implode('').'
    '; 19 | } 20 | 21 | public function form() 22 | { 23 | return collect($this->options)->map(function ($value, $key) { 24 | $field = Check::make($value, $this->column.'['.$key.']'); 25 | return $field->formHtml(); 26 | })->implode(''); 27 | } 28 | 29 | public function formHtml() 30 | { 31 | $title = Heading::make($this->title); 32 | return $title->form().$this->form(); 33 | } 34 | 35 | public function options($array) 36 | { 37 | if (!$this->showOnHere()) { 38 | return $this; 39 | } 40 | if (is_callable($array)) { 41 | $array = $array(); 42 | } 43 | $this->options = $array; 44 | return $this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Inputs/Code.php: -------------------------------------------------------------------------------- 1 | attributes['data-type'] = 'codeeditor'; 13 | $this->attributes['data-color'] = 'black'; 14 | $this->attributes['data-lang'] = $this->lang; 15 | 16 | return html() 17 | ->textarea($this->column, $this->default_value) 18 | ->attributes($this->attributes); 19 | } 20 | 21 | public function getValue($object) 22 | { 23 | $value = parent::getValue($object); 24 | if ($this->lang == 'json') { 25 | $value = json_decode($value); 26 | $value = json_encode($value, JSON_PRETTY_PRINT); 27 | } 28 | return '' . $value . ''; 29 | } 30 | 31 | public function setLang($lang) 32 | { 33 | $this->lang = $lang; 34 | return $this; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Inputs/Date.php: -------------------------------------------------------------------------------- 1 | resource?->object ?? false) { 12 | $this->default_value = $this->getValue($this->resource->object); 13 | } 14 | return html() 15 | ->date($this->column, $this->default_value) 16 | ->attributes($this->attributes); 17 | } 18 | 19 | public function getValue($object) 20 | { 21 | $column = $this->column; 22 | $value = $object->$column; 23 | if ($value instanceof Carbon) { 24 | return $value->format(config('front.date_format')); 25 | } 26 | 27 | $value = parent::getValue($object); 28 | if (is_object($value)) { 29 | return $value->format('Y-m-d'); 30 | } 31 | return $value; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Inputs/DateTime.php: -------------------------------------------------------------------------------- 1 | resource?->object) { 15 | $this->default_value = $this->getValue($this->resource->object); 16 | } 17 | $this->attributes['pattern'] = $this->pattern; 18 | 19 | return html() 20 | ->datetime($this->column, $this->default_value) 21 | ->attributes($this->attributes); 22 | } 23 | 24 | public function getValue($object) 25 | { 26 | $column = $this->column; 27 | $value = $object->$column; 28 | if ($value instanceof Carbon && config('front.datetime_wrap')) { 29 | $value = $value->{config('front.datetime_wrap')}(); 30 | } 31 | if ($value instanceof Carbon) { 32 | return $value->format(config('front.datetime_format')); 33 | } 34 | 35 | return parent::getValue($object); 36 | } 37 | 38 | public function useSeconds() 39 | { 40 | $this->pattern = '^\d\d\d\d-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01]) (00|[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$'; 41 | $this->input_type = 'datetime'; 42 | return $this; 43 | } 44 | 45 | public function processData($data) 46 | { 47 | if (!isset($data[$this->column]) || $this->input_type != 'frontDatetime') { 48 | return $data; 49 | } 50 | 51 | $data[$this->column] = Carbon::parse($data[$this->column])->format('Y-m-d H:i:s'); 52 | return $data; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Inputs/Disabled.php: -------------------------------------------------------------------------------- 1 | attributes; 12 | $attributes['disabled'] = 'disabled'; 13 | 14 | return html() 15 | ->text($this->column, $this->default_value) 16 | ->attributes($attributes) 17 | . 18 | html() 19 | ->hidden($this->column, $this->default_value) 20 | ->attributes($this->attributes); 21 | } 22 | 23 | public function processData($data) 24 | { 25 | if (!$this->process_input) { 26 | unset($data[$this->column]); 27 | } 28 | return $data; 29 | } 30 | 31 | // To avoid saving the input data 32 | public function processInput($value) 33 | { 34 | $this->process_input = $value; 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Inputs/File.php: -------------------------------------------------------------------------------- 1 | file($this->column) 18 | ->attributes($this->attributes); 19 | } 20 | 21 | public function setDirectory($directory) 22 | { 23 | $this->directory = $directory; 24 | return $this; 25 | } 26 | 27 | public function processData($data) 28 | { 29 | if (!isset($data[$this->column])) { 30 | return $data; 31 | } 32 | $file = Storage::putFile($this->directory, $data[$this->column], $this->visibility); 33 | $url = Storage::url($file); 34 | 35 | // Save original name in a column if set 36 | if (!is_null($this->original_name_column)) { 37 | $data[$this->original_name_column] = $data[$this->column]->getClientOriginalName(); 38 | } 39 | $data[$this->column] = $url; 40 | return $data; 41 | } 42 | 43 | public function getValue($object) 44 | { 45 | $value = parent::getValue($object); 46 | return view('front::inputs.file', compact('value')); 47 | } 48 | 49 | public function setOriginalNameColumn($value) 50 | { 51 | $this->original_name_column = $value; 52 | return $this; 53 | } 54 | 55 | public function setVisibility($visibility) 56 | { 57 | $this->visibility = $visibility; 58 | return $this; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Inputs/HasOneThrough.php: -------------------------------------------------------------------------------- 1 | relation = Str::snake($column); 25 | $this->column = 'has_one_trough:' . $title; 26 | $this->extra = $extra; 27 | $this->source = $source; 28 | 29 | if (!isset($this->extra)) { 30 | $front = Str::singular($this->relation); 31 | $front = ucfirst(Str::camel($front)); 32 | $this->extra = $title; 33 | } 34 | 35 | $this->model_name = $this->extra; 36 | $this->relation_front = Front::makeResource($this->model_name, $this->source); 37 | $class = $this->relation_front->getModel(); 38 | $this->title = $this->relation_front->label; 39 | 40 | $this->load(); 41 | } 42 | 43 | public function setResource($resource) 44 | { 45 | $relation = $this->relation; 46 | if (!method_exists($resource, 'getModel')) { 47 | return parent::setResource($resource); 48 | } 49 | 50 | $class = $resource->getModel(); 51 | $model = new $class(); 52 | if (method_exists($model, $relation)) { 53 | $relation_function = $model->$relation(); 54 | $this->relation_function = $relation_function; 55 | } else { 56 | abort(506, 'The relation ' . $relation . ' does not exists in ' . $class); 57 | } 58 | return parent::setResource($resource); 59 | } 60 | 61 | public function getValue($object) 62 | { 63 | $relation = $this->relation; 64 | if (!is_object($object->$relation)) { 65 | return '--'; 66 | } 67 | 68 | $title_field = $this->search_field ?? $this->relation_front->search_title; 69 | $value = $object->$relation->$title_field; 70 | if (!isset($this->link)) { 71 | $this->link = $this->relation_front->getBaseUrl() . '/' . $object->$relation->getKey(); 72 | } 73 | if (!isset($value)) { 74 | return '--'; 75 | } 76 | return $value; 77 | } 78 | 79 | public function form() 80 | { 81 | $relation_front = $this->relation_front; 82 | 83 | $model = $this->relation_front->getModel(); 84 | $model = new $model(); 85 | 86 | if (isset($this->force_query)) { 87 | $force_query = $this->force_query; 88 | $query = $force_query($model); 89 | } else { 90 | $query = $this->relation_front->globalIndexQuery(); 91 | } 92 | 93 | if (isset($this->filter_query)) { 94 | $filter_query = $this->filter_query; 95 | $query = $filter_query($query); 96 | } 97 | 98 | $options = $query->get(); 99 | if (isset($this->filter_collection)) { 100 | $filter_collection = $this->filter_collection; 101 | $options = $filter_collection($options); 102 | } 103 | 104 | // Get default value 105 | $relation = $this->relation; 106 | $value = $this->resource?->object?->$relation?->getKey(); 107 | if (isset($value)) { 108 | $this->default_value = $value; 109 | $this->default_value_force = true; 110 | } 111 | 112 | $title = $this->search_field ?? $this->relation_front->search_title; 113 | $options = $options->pluck($title, $model->getKeyName()); 114 | $select = Select::make($this->title, $this->column) 115 | ->options($options) 116 | ->default($this->default_value, $this->default_value_force) 117 | ->size($this->size) 118 | ->setEmptyTitle($this->empty_title) 119 | ->withMeta($this->attributes) 120 | ->setPlaceholder($this->show_placeholder); 121 | return $select->form(); 122 | } 123 | 124 | public function hidePlaceholder() 125 | { 126 | $this->show_placeholder = false; 127 | return $this; 128 | } 129 | 130 | public function defaultData($data) 131 | { 132 | $this->default_data = $data; 133 | return $this; 134 | } 135 | 136 | public function processData($data) 137 | { 138 | if (!isset($data[$this->column]) || is_null($data[$this->column])) { 139 | unset($data[$this->column]); 140 | return $data; 141 | } 142 | 143 | $value = $data[$this->column]; 144 | $relation = $this->relation; 145 | $column = $this->relation_function->getForeignKeyName(); 146 | 147 | // Remove items on the relation 148 | $this->relation_function->getParent()->query()->where($this->relation_function->getFirstKeyName(), $this->resource->object->$column)->delete(); 149 | 150 | // Create new item. Consider it works only with 1 item related. 151 | $this->relation_function->getParent()->create(array_merge($this->default_data, [ 152 | $this->relation_function->getFirstKeyName() => $this->resource->object->$column, 153 | $this->relation_function->getSecondLocalKeyName() => $value 154 | ])); 155 | 156 | unset($data[$this->column]); 157 | return $data; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/Inputs/Hidden.php: -------------------------------------------------------------------------------- 1 | hidden($this->$column_to_use, $this->default_value) 17 | ->attributes($this->attributes); 18 | } 19 | 20 | public function formHtml() 21 | { 22 | return $this->form(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Inputs/ID.php: -------------------------------------------------------------------------------- 1 | title = 'ID'; 15 | } 16 | } 17 | 18 | public function form() 19 | { 20 | return; 21 | } 22 | 23 | public function getValue($object) 24 | { 25 | return $object->getKey(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Inputs/ImageCropper.php: -------------------------------------------------------------------------------- 1 | attributes['data-type'] = 'cropper'; 21 | $this->attributes['data-image'] = $id; 22 | $this->attributes['data-width'] = $this->width; 23 | $this->attributes['data-ratio'] = $this->ratio; 24 | 25 | if (isset($this->handler)) { 26 | $this->attributes['data-handler'] = $function; 27 | } 28 | 29 | if (isset($this->max_sizes)) { 30 | $this->attributes['data-max-sizes'] = $this->max_sizes[0] . ',' . $this->max_sizes[1]; 31 | } 32 | 33 | if (isset($this->min_sizes)) { 34 | $this->attributes['data-min-sizes'] = $this->min_sizes[0] . ',' . $this->min_sizes[1]; 35 | } 36 | 37 | $html = ''; 38 | 39 | $html .= html() 40 | ->hidden($this->column, $this->default_value) 41 | ->attributes($this->attributes); 42 | 43 | if (isset($this->handler)) { 44 | $handler = $this->handler; 45 | $html .= ''; 46 | } 47 | 48 | return $html; 49 | } 50 | 51 | public function setImage($image) 52 | { 53 | $this->image = $image; 54 | return $this; 55 | } 56 | 57 | public function setWidth($width) 58 | { 59 | $this->width = $width; 60 | return $this; 61 | } 62 | 63 | public function setRatio($ratio) 64 | { 65 | $this->ratio = $ratio; 66 | return $this; 67 | } 68 | 69 | public function setMaxSizes($width, $height) 70 | { 71 | $this->max_sizes = [$width, $height]; 72 | return $this; 73 | } 74 | 75 | public function setMinSizes($width, $height) 76 | { 77 | $this->min_sizes = [$width, $height]; 78 | return $this; 79 | } 80 | 81 | public function setHandler($handler) 82 | { 83 | $this->handler = $handler; 84 | return $this; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Inputs/ImagePointer.php: -------------------------------------------------------------------------------- 1 | attributes['data-type'] = 'image-coordinate'; 15 | $this->attributes['data-image'] = $id; 16 | $html = ''; 17 | 18 | $html .= html() 19 | ->hidden($this->column, $this->default_value) 20 | ->attributes($this->attributes); 21 | 22 | return $html; 23 | } 24 | 25 | public function setImage($image) 26 | { 27 | $this->image = $image; 28 | return $this; 29 | } 30 | 31 | public function setWidth($width) 32 | { 33 | $this->width = $width; 34 | return $this; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Inputs/Images.php: -------------------------------------------------------------------------------- 1 | column])) { 39 | return $data; 40 | } 41 | if (!$this->save) { 42 | return $data; 43 | } 44 | 45 | $all_data = []; 46 | unset($data['_token']); 47 | $files = $data[$this->column]; 48 | foreach ($files as $file) { 49 | $data[$this->column] = $file; 50 | $all_data[] = $data; 51 | } 52 | 53 | return collect($all_data)->map(function ($data) { 54 | // Save original file 55 | $file = $data[$this->column]; 56 | $result = $this->saveOriginalFile($data, $file); 57 | $url = $result['url']; 58 | $file_name = $result['file_name']; 59 | 60 | // New sizes 61 | foreach ($this->thumbnails as $thumbnail) { 62 | $this->saveNewSize($file, $file_name, $thumbnail['width'], $thumbnail['height'], $thumbnail['prefix'], $thumbnail['fit']); 63 | } 64 | 65 | // Assign data to request 66 | $data[$this->column] = $url; 67 | 68 | // Save original name in a column if set 69 | if (!is_null($this->original_name_column)) { 70 | $data[$this->original_name_column] = $file->getClientOriginalName(); 71 | } 72 | return $data; 73 | })->all(); 74 | } 75 | 76 | public function validate($data) 77 | { 78 | $name = $this->column; 79 | $attribute_name = $this->title; 80 | $rules = [ 81 | $name . '.*' => ['image', 'mimes:jpeg,png,jpg,gif,svg,webp', 'max:' . $this->max_size] 82 | ]; 83 | $attributes = [ 84 | $name . '.*' => $attribute_name 85 | ]; 86 | 87 | Validator::make($data, $rules, [], $attributes)->validate(); 88 | } 89 | 90 | public function setOriginalNameColumn($value) 91 | { 92 | $this->original_name_column = $value; 93 | return $this; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Inputs/InputGroup.php: -------------------------------------------------------------------------------- 1 | before = $before; 16 | $this->input = $input; 17 | $this->after = $after; 18 | } 19 | 20 | public static function make($before = null, $input = null, $after = null) 21 | { 22 | return new static($before, $input, $after); 23 | } 24 | 25 | public function form() 26 | { 27 | $group = $this; 28 | return view('front::input-group', compact('group'))->render(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Inputs/Money.php: -------------------------------------------------------------------------------- 1 | attributes['step'] = '.01'; 10 | 11 | $input = html() 12 | ->number($this->column, $this->default_value) 13 | ->attributes($this->attributes); 14 | 15 | return InputGroup::make('$', $input)->form(); 16 | } 17 | 18 | public function getValue($object) 19 | { 20 | $value = parent::getValue($object); 21 | if (!is_numeric($value)) { 22 | return $value; 23 | } 24 | return '$' . number_format($value, 2); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Inputs/MorphMany.php: -------------------------------------------------------------------------------- 1 | morph_column = $relation_function->getMorphType(); 12 | return $this->column.'='.$resource->object->getKey().'&'.$this->morph_column.'='.$relation_function->getMorphClass(); 13 | } 14 | 15 | public function getColumnsToHide() 16 | { 17 | return [$this->column, $this->morph_column]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Inputs/MorphToMany.php: -------------------------------------------------------------------------------- 1 | attributes['step'] = $this->getStep(); 12 | 13 | return html() 14 | ->number($this->column, $this->default_value) 15 | ->attributes($this->attributes); 16 | } 17 | 18 | public function decimals($decimals) 19 | { 20 | $this->decimals = $decimals; 21 | return $this; 22 | } 23 | 24 | private function getStep() 25 | { 26 | if (is_null($this->decimals)) { 27 | return 'any'; 28 | } 29 | if ($this->decimals == 0) { 30 | return 1; 31 | } 32 | return 1 / pow(10, $this->decimals); 33 | } 34 | 35 | public function getValue($object) 36 | { 37 | $value = parent::getValue($object); 38 | if (is_null($this->decimals) || !is_numeric($value) || !is_numeric($this->decimals)) { 39 | return $value; 40 | } 41 | return round($value, $this->decimals); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Inputs/Password.php: -------------------------------------------------------------------------------- 1 | password($this->column) 14 | ->attributes($this->attributes); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Inputs/Percentage.php: -------------------------------------------------------------------------------- 1 | attributes['step'] = '.01'; 12 | 13 | $input = html() 14 | ->number($this->column, $this->default_value) 15 | ->attributes($this->attributes); 16 | 17 | return InputGroup::make(null, $input, '%')->form(); 18 | } 19 | 20 | public function decimals($decimals) 21 | { 22 | $this->decimals = $decimals; 23 | return $this; 24 | } 25 | 26 | public function getValue($object) 27 | { 28 | $value = parent::getValue($object); 29 | if (is_null($this->decimals) || !is_numeric($value) || !is_numeric($this->decimals)) { 30 | return $value . '%'; 31 | } 32 | return round($value, $this->decimals) . '%'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Inputs/Select.php: -------------------------------------------------------------------------------- 1 | options; 15 | return $options[$value] ?? $value; 16 | } 17 | 18 | public function form() 19 | { 20 | $select = html() 21 | ->select($this->column, $this->options) 22 | ->attributes($this->attributes); 23 | 24 | if($this->default_value) { 25 | $select = $select->value($this->default_value); 26 | } 27 | if ($this->show_placeholder) { 28 | $select = $select->placeholder(__($this->empty_title)); 29 | } 30 | 31 | return $select; 32 | } 33 | 34 | public function options($array) 35 | { 36 | if (!$this->showOnHere()) { 37 | return $this; 38 | } 39 | if (is_callable($array)) { 40 | $array = $array(); 41 | } 42 | $this->options = collect($array)->map(function ($item) { 43 | if (!is_string($item)) { 44 | return $item; 45 | } 46 | return __($item); 47 | }); 48 | return $this; 49 | } 50 | 51 | public function setEmptyTitle($value = null) 52 | { 53 | if (is_null($value)) { 54 | return $this; 55 | } 56 | 57 | $this->empty_title = $value; 58 | return $this; 59 | } 60 | 61 | public function multiple() 62 | { 63 | $this->attributes['multiple'] = 'multiple'; 64 | $this->column = $this->column . '[]'; 65 | $this->hidePlaceholder(); 66 | return $this; 67 | } 68 | 69 | public function hidePlaceholder() 70 | { 71 | $this->show_placeholder = false; 72 | return $this; 73 | } 74 | 75 | public function setPlaceholder($value) 76 | { 77 | $this->show_placeholder = $value; 78 | return $this; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Inputs/Text.php: -------------------------------------------------------------------------------- 1 | text($this->getColumn(), $this->default_value) 11 | ->attributes($this->attributes); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Inputs/Textarea.php: -------------------------------------------------------------------------------- 1 | textarea($this->column, $this->default_value) 15 | ->attributes($this->attributes); 16 | } 17 | 18 | public function getValue($object) 19 | { 20 | $value = parent::getValue($object); 21 | if ($this->limit_on_index != false && $this->source == 'index') { 22 | return Str::limit($value, $this->limit_on_index); 23 | } 24 | return nl2br($value); 25 | } 26 | 27 | public function limitOnIndex($limit = 80) 28 | { 29 | $this->limit_on_index = $limit; 30 | return $this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Inputs/Time.php: -------------------------------------------------------------------------------- 1 | attributes['pattern'] = $this->pattern; 13 | $type = $this->input_type; 14 | 15 | if ($type === 'text') { 16 | $form = html()->text($this->column, $this->default_value); 17 | } elseif ($type === 'time') { 18 | $form = html()->time($this->column, $this->default_value); 19 | } 20 | 21 | return $form->attributes($this->attributes); 22 | } 23 | 24 | public function ignoreSeconds() 25 | { 26 | $this->pattern = '([01]?[0-9]|2[0-3]):[0-5][0-9]'; 27 | $this->input_type = 'time'; 28 | return $this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Inputs/Trix.php: -------------------------------------------------------------------------------- 1 | 1000, 10 | 'height' => 1000, 11 | 'directory' => 'trix' 12 | ]; 13 | 14 | public function form() 15 | { 16 | $this->attributes['data-type'] = 'wysiwyg'; 17 | $this->attributes['data-lang'] = app()->getLocale(); 18 | $this->attributes['data-upload-url'] = url('api/laravel-front/upload-image') . '?variables=' . json_encode($this->variables); 19 | 20 | return html() 21 | ->textarea($this->column, $this->default_value) 22 | ->attributes($this->attributes); 23 | } 24 | 25 | public function originalSize($width, $height) 26 | { 27 | $this->variables['width'] = $width; 28 | $this->variables['height'] = $height; 29 | return $this; 30 | } 31 | 32 | public function setDirectory($directory) 33 | { 34 | $this->variables['directory'] = $directory; 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Jobs/ActionShow.php: -------------------------------------------------------------------------------- 1 | front = $front; 24 | $this->object = $object; 25 | $this->action = $action; 26 | $this->store = $store; // Function to execute in case there aren't any fields 27 | } 28 | 29 | /** 30 | * Execute the job. 31 | * 32 | * @return void 33 | */ 34 | public function handle() 35 | { 36 | $object = $this->object; 37 | 38 | // Modify with indexResult 39 | if (isset($object)) { 40 | $result = collect([$object]); 41 | $result = $this->front->indexResult($result); 42 | $object = $result->first(); 43 | } 44 | 45 | // Search the individual action 46 | if (isset($object)) { 47 | $action = $this->front->searchAction($this->action); 48 | } else { 49 | $action = $this->front->searchIndexAction($this->action); 50 | } 51 | 52 | // Show message if wasn't found 53 | if (!is_object($action)) { 54 | abort(406, "Action wasn't found: {$this->action}"); 55 | } 56 | 57 | // Dont show action if is not showable 58 | if (!$action->show) { 59 | abort(404); 60 | } 61 | 62 | // Set front 63 | $action = $action->setFront($this->front); 64 | 65 | // Set object to action 66 | if (isset($object)) { 67 | $action = $action->setObject($object); 68 | } 69 | 70 | $result = $action->fields(); 71 | 72 | // If returns a response so dont do any more 73 | if (isResponse($result)) { 74 | return $result; 75 | } 76 | 77 | // If doesnt have fields return action 78 | if (!is_array($result)) { 79 | return $action; 80 | } 81 | 82 | // Detect if dont have fields or if are just hidden inputs process inmediately 83 | $visible_fields = collect($result)->filter(function ($item) { 84 | return get_class($item) != 'WeblaborMx\Front\Inputs\Hidden'; 85 | }); 86 | if ($visible_fields->count() == 0) { 87 | $function = $this->store; 88 | return $function(); 89 | } 90 | 91 | // Returns action 92 | return $action; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Jobs/ActionStore.php: -------------------------------------------------------------------------------- 1 | front = $front; 24 | $this->object = $object; 25 | $this->action = $action; 26 | $this->request = $request; 27 | } 28 | 29 | /** 30 | * Execute the job. 31 | * 32 | * @return void 33 | */ 34 | public function handle() 35 | { 36 | // Search the individual action 37 | if (isset($this->object)) { 38 | $action = $this->front->searchAction($this->action); 39 | } else { 40 | $action = $this->front->searchIndexAction($this->action); 41 | } 42 | 43 | // Show message if wasn't found 44 | if (!is_object($action)) { 45 | abort(406, "Action wasn't found: {$this->action}"); 46 | } 47 | 48 | // Dont show action if is not showable 49 | if (!$action->show) { 50 | abort(404); 51 | } 52 | 53 | // Set front 54 | $action = $action->setFront($this->front); 55 | 56 | // Set object to action and validate 57 | if (isset($this->object)) { 58 | $action = $action->setObject($this->object); 59 | } 60 | 61 | // Get data to be saved 62 | $data = $action->processData($this->request->all()); 63 | 64 | // Validate object 65 | $action->validate($data); 66 | 67 | // Process data after validation 68 | $data = $action->processDataAfterValidation($data); 69 | 70 | // Get request 71 | $request = $this->request; 72 | $request = $request->merge($data); 73 | 74 | // Execute action 75 | if (isset($this->object)) { 76 | $result = $action->handle($this->object, $request); 77 | } else { 78 | $result = $action->handle($request); 79 | } 80 | 81 | // If is front fields 82 | if ($this->isFrontable($result)) { 83 | $result = $this->makeFrontable($result, [ 84 | 'title' => $action->title, 85 | ], $this->front); 86 | } 87 | 88 | // If returns a response so dont do any more 89 | if (isResponse($result)) { 90 | $this->request->flash(); 91 | return $result; 92 | } 93 | 94 | // If returns empty so show successfull message 95 | if (!isset($result)) { 96 | flash(__(':name action executed successfully', ['name' => $action->title,]))->success(); 97 | } 98 | 99 | // In case they return a flash answer 100 | $this->request->flash(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Jobs/FrontDestroy.php: -------------------------------------------------------------------------------- 1 | front = $front; 18 | $this->object = $object; 19 | } 20 | 21 | /** 22 | * Execute the job. 23 | * 24 | * @return void 25 | */ 26 | public function handle() 27 | { 28 | $continue = $this->front->destroy($this->object); 29 | if (is_bool($continue) && !$continue) { 30 | return false; 31 | } 32 | 33 | // Process inputs actions for when is removed 34 | $this->front->processRemoves($this->object); 35 | 36 | // Delete the object 37 | $this->object->delete(); 38 | 39 | // Show success message 40 | flash(__(':name deleted successfully', ['name' => $this->front->label]))->success(); 41 | 42 | // Return true 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Jobs/FrontIndex.php: -------------------------------------------------------------------------------- 1 | front = $front; 21 | $this->base = $base; 22 | } 23 | 24 | /** 25 | * Execute the job. 26 | * 27 | * @return void 28 | */ 29 | public function handle() 30 | { 31 | // Redirect if filters asks to do it 32 | $redirect_url = $this->front->redirects(); 33 | if (isset($redirect_url)) { 34 | return redirect($redirect_url); 35 | } 36 | 37 | // Get results 38 | $objects = $this->front->globalIndexQuery(); 39 | 40 | // Detect if crud is just for 1 item and redirects 41 | if (!Str::contains(get_class($objects), 'Illuminate\Database\Eloquent')) { 42 | $url = $this->base.'/'.$objects->getKey().'/edit'; 43 | return redirect($url); 44 | } 45 | 46 | // If is normal query paginate results 47 | $result = $this->paginate($objects); 48 | 49 | // If the result needs to be modified just modify it 50 | $result = $this->result($result); 51 | 52 | // If filter has different default values check who is not empty 53 | $result = $this->multipleRedirects($result); 54 | 55 | // Call the action to be done after is accessed 56 | $this->front->index(); 57 | 58 | return $result; 59 | } 60 | 61 | private function multipleRedirects($result) 62 | { 63 | // If doesnt have results and is redirect 64 | if (request()->filled('is_redirect') && $result->count() == 0) { 65 | // Get url to send 66 | $redirect_url = $this->front->redirects(false); 67 | 68 | // If there isn't any redirect url don't do anything 69 | if (!isset($redirect_url) || url()->full() == $redirect_url) { 70 | return $result; 71 | } 72 | 73 | // Generate new url 74 | $current_query = request()->query(); 75 | $new_query = explode('?', $redirect_url)[1]; 76 | $new_query = collect(explode('&', $new_query))->mapWithKeys(function ($item) { 77 | $item = explode('=', $item); 78 | return [$item[0] => $item[1]]; 79 | })->toArray(); 80 | 81 | // Send to new url 82 | if (isset($redirect_url) && $current_query != $new_query) { 83 | return redirect($redirect_url); 84 | } 85 | } 86 | return $result; 87 | } 88 | 89 | private function paginate($objects) 90 | { 91 | // Get cache time to cache 92 | $cache = $this->front->cacheFor(); 93 | 94 | // If not time set so paginate directly 95 | if ($cache == false || !in_array('indexQuery', $this->front->cache)) { 96 | return $objects->paginate($this->front->pagination); 97 | } 98 | 99 | // Get cache key 100 | $cache_key = $this->getPaginateCacheKey($objects); 101 | 102 | // Make the pagination 103 | return Cache::remember($cache_key, $cache, function () use ($objects) { 104 | return $objects->paginate($this->front->pagination); 105 | }); 106 | } 107 | 108 | private function getPaginateCacheKey($objects) 109 | { 110 | $request = collect(request()->all())->whereNotNull()->map(function ($item, $key) { 111 | return $key.'-'.$item; 112 | })->implode(','); 113 | $key = 'front:'.$request.':'; 114 | $key .= $objects->toSql(); 115 | $key = hash('sha256', $key); 116 | return $key; 117 | } 118 | 119 | public function result($result) 120 | { 121 | // Get cache time to cache 122 | $cache = $this->front->cacheFor(); 123 | 124 | // If not time set so paginate directly 125 | if ($cache == false || !in_array('indexResult', $this->front->cache)) { 126 | return $this->front->indexResult($result); 127 | } 128 | 129 | // Get cache key 130 | $cache_key = $this->getResultCacheKey($result); 131 | 132 | // Make the pagination 133 | return Cache::remember($cache_key, $cache, function () use ($result) { 134 | return $this->front->indexResult($result); 135 | }); 136 | } 137 | 138 | private function getResultCacheKey($result) 139 | { 140 | $key_name = $result->first()->getKeyName(); 141 | $key = get_class($this).':result:'.$result->pluck($key_name)->implode('|'); 142 | $key = hash('sha256', $key); 143 | return $key; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/Jobs/FrontSearch.php: -------------------------------------------------------------------------------- 1 | front = $front; 18 | $this->request = $request; 19 | } 20 | 21 | /** 22 | * Execute the job. 23 | * 24 | * @return void 25 | */ 26 | public function handle() 27 | { 28 | // Get title column for element 29 | $title = request()->filled('search_field') ? request()->search_field : $this->front->search_title; 30 | 31 | // Get results query 32 | $result = $this->front->globalIndexQuery(); 33 | 34 | // Get query if sent 35 | if ($this->request->filled('filter_query')) { 36 | $query = json_decode($this->request->filter_query); 37 | $query = unserialize($query); 38 | $query = $query->getClosure(); 39 | $result = $query($result); 40 | } 41 | 42 | // Get search filter 43 | $filter = config('front.default_search_filter'); 44 | $search_filter = new $filter(); 45 | 46 | // Search results and map with format 47 | $result = $search_filter->apply($result, $this->request->term); 48 | $result = $result->limit($this->front->search_limit)->get()->map(function ($item) use ($title) { 49 | return [ 50 | 'label' => $item->$title, 51 | 'id' => $item->getKey(), 52 | 'value' => $item->$title 53 | ]; 54 | })->sortBy('label'); 55 | 56 | // If there are results so print 57 | if ($result->count() > 0) { 58 | print json_encode($result); 59 | return; 60 | } 61 | 62 | // If there aren't results show that nothing was found 63 | $result = [[ 64 | 'label' => __('Nothing found'), 65 | 'id' => 0, 66 | 'value' => __('Nothing found') 67 | ]]; 68 | print json_encode($result); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Jobs/FrontShow.php: -------------------------------------------------------------------------------- 1 | front = $front; 20 | $this->object = $object; 21 | } 22 | 23 | /** 24 | * Execute the job. 25 | * 26 | * @return void 27 | */ 28 | public function handle() 29 | { 30 | $object = $this->object; 31 | 32 | // Executing when showing an item 33 | $this->front->show($object); 34 | 35 | // Modify with indexResult 36 | $result = collect([$object]); 37 | $result = $this->front->indexResult($result); 38 | $object = $result->first(); 39 | 40 | return $object; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Jobs/FrontStore.php: -------------------------------------------------------------------------------- 1 | request = $request; 22 | $this->front = $front; 23 | } 24 | 25 | /** 26 | * Execute the job. 27 | * 28 | * @return void 29 | */ 30 | public function handle() 31 | { 32 | // Get data to be saved 33 | $data = $this->front->processData($this->request->all()); 34 | if (isResponse($data)) { 35 | return $data; 36 | } 37 | 38 | // Validate 39 | $this->front->validate($data); 40 | 41 | // Process data after validation 42 | $data = $this->front->processDataAfterValidation($data); 43 | 44 | // Process data Before saving 45 | $data = $this->front->processDataBeforeSaving($data); 46 | 47 | // Make work with arrays 48 | if (!$this->isArrayOfArrays($data)) { 49 | $data = [$data]; 50 | } 51 | 52 | // Iterate with all info 53 | foreach ($data as $result) { 54 | // Create the object 55 | $object = $this->front->create($result); 56 | 57 | if (isResponse($object)) { 58 | return $object; 59 | } 60 | 61 | // Process actions after save 62 | $this->front->processAfterSave($object, $this->request); 63 | 64 | // Call the action to be done after is created 65 | $this->front->store($object, $this->request); 66 | } 67 | 68 | // Show success message 69 | flash(__(':name created successfully', ['name' => $this->front->label]))->success(); 70 | 71 | // Redirect if there was a redirect value on the form 72 | if ($this->request->filled('redirect_url')) { 73 | $url = $this->request->redirect_url; 74 | $url = str_replace('{base_url}', $this->front->getBaseUrl(), $url); 75 | $url = str_replace('{key}', $object->getKey(), $url); 76 | return redirect($url); 77 | } 78 | 79 | // Return the created object 80 | return $object; 81 | } 82 | 83 | private function isArrayOfArrays($array) 84 | { 85 | if (!is_array($array)) { 86 | return false; 87 | } 88 | $result = true; 89 | foreach ($array as $children) { 90 | if (!is_array($children)) { 91 | $result = false; 92 | } 93 | } 94 | return $result; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Jobs/FrontUpdate.php: -------------------------------------------------------------------------------- 1 | request = $request; 19 | $this->front = $front; 20 | $this->object = $object; 21 | } 22 | 23 | /** 24 | * Execute the job. 25 | * 26 | * @return void 27 | */ 28 | public function handle() 29 | { 30 | // Get data to be saved 31 | $data = $this->front->processData($this->request->all()); 32 | if (isResponse($data)) { 33 | return $data; 34 | } 35 | 36 | // Validate 37 | $this->front->validate($data); 38 | 39 | // Process data after validation 40 | $data = $this->front->processDataAfterValidation($data); 41 | 42 | // Process data Before saving 43 | $data = $this->front->processDataBeforeSaving($data); 44 | 45 | // Call the action to be done before is updated 46 | $this->front->beforeUpdate($this->object, $this->request); 47 | 48 | // Update the object 49 | $this->object->update($data); 50 | 51 | // Process actions after save 52 | $this->front->processAfterSave($this->object, $this->request); 53 | 54 | // Call the action to be done after is updated 55 | $this->front->update($this->object, $this->request); 56 | 57 | // Show success message 58 | flash(__(':name updated successfully', ['name' => $this->front->label]))->success(); 59 | 60 | // Redirect if there was a redirect value on the form 61 | if ($this->request->filled('redirect_url')) { 62 | return redirect($this->request->redirect_url); 63 | } 64 | 65 | // Return the created object 66 | return $this->object; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Jobs/MassiveEditShow.php: -------------------------------------------------------------------------------- 1 | front = $front; 19 | $this->object = $object; 20 | $this->key = $key; 21 | } 22 | 23 | /** 24 | * Execute the job. 25 | * 26 | * @return void 27 | */ 28 | public function handle() 29 | { 30 | // Set session 31 | \Cache::store('array')->put('is_massive', true); 32 | 33 | // Check if relationship exists 34 | if (!isset($this->front->showRelations()[$this->key])) { 35 | abort(406, 'Key isnt correct'); 36 | } 37 | 38 | // Get relationship input 39 | $input = $this->front->showRelations()[$this->key]; 40 | $input_front = $input->front->addData($this->front->data); 41 | 42 | // Get relationship data 43 | $result = $input->getResults($this->object); 44 | if (!in_array(get_class($result), ['Illuminate\Support\Collection', 'Illuminate\Database\Eloquent\Collection'])) { 45 | $result = $result->get(); 46 | } 47 | 48 | // Return generated data 49 | return compact('input', 'input_front', 'result'); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Jobs/MassiveIndexEditShow.php: -------------------------------------------------------------------------------- 1 | front = $front; 19 | } 20 | 21 | /** 22 | * Execute the job. 23 | * 24 | * @return void 25 | */ 26 | public function handle() 27 | { 28 | // Set session 29 | \Cache::store('array')->put('is_massive', true); 30 | 31 | // Get objects 32 | $result = $this->front->globalIndexQuery()->limit($this->front->pagination)->get(); 33 | 34 | // Return generated data 35 | return compact('result'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Jobs/MassiveIndexEditStore.php: -------------------------------------------------------------------------------- 1 | front = $front; 22 | $this->request = $request; 23 | } 24 | 25 | /** 26 | * Execute the job. 27 | * 28 | * @return void 29 | */ 30 | public function handle() 31 | { 32 | // Get data that should be added to all data 33 | $basic_data = collect($this->request->except(['_token', 'submitName', 'relation_front', 'relation_id', 'redirect_url']))->filter(function ($item) { 34 | return !is_array($item) && !is_null($item); 35 | }); 36 | 37 | // Get request data 38 | $data = $this->request->all(); 39 | 40 | // Modify data if exists a massive class 41 | if (is_object($this->front->massive_class)) { 42 | $data = $this->front->massive_class->processData($data); 43 | } 44 | 45 | // Save data on table 46 | $this->saveData($data, $basic_data); 47 | 48 | // Declare it as null 49 | $return = null; 50 | 51 | // If another button is pressed is because the presence of massive class 52 | if (isset($this->request->submitName) && is_object($this->front->massive_class)) { 53 | $function = $this->request->submitName; 54 | $return = $this->front->massive_class->$function($data); 55 | } 56 | 57 | // Show successfull message 58 | if (is_null($return)) { 59 | flash(__(':name updated successfully', ['name' => $this->front->plural_label]))->success(); 60 | } 61 | } 62 | 63 | private function saveData($data, $basic_data) 64 | { 65 | $objects = collect($data)->filter(function ($item) { 66 | // Just show arrays 67 | return is_array($item); 68 | })->filter(function ($item, $key) { 69 | // Avoid adding data with only nulls 70 | $values = collect($item)->values()->whereNotNull(); 71 | 72 | // Get required fields 73 | $required_fields = collect($this->front->getRules('index'))->filter(function ($item) { 74 | return in_array('required', $item); 75 | })->keys(); 76 | 77 | // Check if required fields have a value 78 | $required_fields_exist = $required_fields->mapWithKeys(function ($column) use ($item) { 79 | return [$column => isset($item[$column])]; 80 | }); 81 | 82 | // Validation 83 | $required_values_result = $required_fields_exist->values()->unique(); 84 | $has_required_values = $required_fields->count() == 0 || ($required_values_result->count() == 1 && $required_values_result->first() == true); 85 | 86 | // Show message error if is not a new field 87 | if (!$has_required_values && !Str::contains($key, 'new')) { 88 | $missing_columns = $required_fields_exist->filter(function ($item) { 89 | return !$item; 90 | })->keys()->implode(', '); 91 | flash()->warning('Row '.$key.' need the next required fields: '.$missing_columns.'. Update ignored.'); 92 | } 93 | return $values->count() > 1 && $has_required_values; 94 | })->map(function ($data, $key) use ($basic_data) { 95 | // If there is a new column save it instead of updating 96 | if (Str::contains($key, 'new')) { 97 | $data = $basic_data->merge($data)->toArray(); 98 | $model = $this->front->model; 99 | $object = $model::create($data); 100 | 101 | // Call the action to be done after is created 102 | $this->front->store($object, $data); 103 | return $object; 104 | } 105 | 106 | // Get models data 107 | $results = $this->front->globalIndexQuery()->limit($this->front->pagination)->get(); 108 | 109 | // If results is not a query get it individually 110 | try { 111 | $item = $results->find($key); 112 | } catch (\Exception $e) { 113 | $model = $this->front->model; 114 | $item = $model::find($key); 115 | } 116 | 117 | // Call the action to be done before is updated 118 | $this->front->beforeUpdate($item, $data); 119 | 120 | // Update data 121 | $item->update($data); 122 | 123 | // Call the action to be done after is updated 124 | $this->front->update($item, $data); 125 | 126 | return $item; 127 | }); 128 | 129 | // Call the action to be done after is updated 130 | $this->front->afterMassive($objects); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Massives/Massive.php: -------------------------------------------------------------------------------- 1 | 'Save and Update Team Stats'] 16 | * When clicking the button will execute saveAndUpdateTeamStats() function 17 | **/ 18 | 19 | public $buttons = []; 20 | 21 | /** 22 | * If you want to modify the request data gotten just update it with this funciton 23 | **/ 24 | 25 | public function processData($request) 26 | { 27 | return $request; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Pages/Page.php: -------------------------------------------------------------------------------- 1 | route = $this->getParameters([], true); 28 | if (!isset($this->title)) { 29 | $title = class_basename(get_class($this)); 30 | $this->title = preg_replace('/(?!^)[A-Z]{2,}(?=[A-Z][a-z])|[A-Z][a-z]/', ' $0', $title); 31 | } 32 | $this->load(); 33 | } 34 | 35 | public function load() 36 | { 37 | // 38 | } 39 | 40 | /* 41 | * Customizable methods 42 | */ 43 | 44 | public function style() 45 | { 46 | return; 47 | } 48 | 49 | public function post() 50 | { 51 | return; 52 | } 53 | 54 | public function put() 55 | { 56 | return; 57 | } 58 | 59 | public function delete() 60 | { 61 | return; 62 | } 63 | 64 | /* 65 | * Executing methods 66 | */ 67 | 68 | public function executeGet($data) 69 | { 70 | return view($this->view, $this->getParameters($data)); 71 | } 72 | 73 | public function executePost($data) 74 | { 75 | $return = $this->post(); 76 | if (isResponse($return)) { 77 | return $return; 78 | } 79 | flash(__('Saved successfully'))->success(); 80 | return back(); 81 | } 82 | 83 | public function executePut($data) 84 | { 85 | $return = $this->post(); 86 | if (isResponse($return)) { 87 | return $return; 88 | } 89 | flash(__('Updated successfully'))->success(); 90 | return back(); 91 | } 92 | 93 | public function executeDelete($data) 94 | { 95 | $return = $this->delete(); 96 | if (isResponse($return)) { 97 | return $return; 98 | } 99 | flash(__('Deleted successfully'))->success(); 100 | return back(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/SecurityProvider.php: -------------------------------------------------------------------------------- 1 | secret = $secret; 19 | } 20 | 21 | /** 22 | * @inheritdoc 23 | */ 24 | public function sign($closure) 25 | { 26 | return array( 27 | 'closure' => $closure, 28 | 'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)), 29 | ); 30 | } 31 | 32 | /** 33 | * @inheritdoc 34 | */ 35 | public function verify(array $data) 36 | { 37 | return true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Texts/Alert.php: -------------------------------------------------------------------------------- 1 | render(); 13 | } 14 | 15 | public function setType($type) 16 | { 17 | $this->type = $type; 18 | return $this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Texts/Button.php: -------------------------------------------------------------------------------- 1 | generateText(); 20 | } 21 | 22 | public function form() 23 | { 24 | $button = $this; 25 | return view('front::texts.button', compact('button'))->render(); 26 | } 27 | 28 | public function addLink($link) 29 | { 30 | $this->link = $link; 31 | return $this; 32 | } 33 | 34 | public function setExtra($extra) 35 | { 36 | $this->extra = $extra; 37 | return $this; 38 | } 39 | 40 | public function setStyle($style) 41 | { 42 | $this->style = $style; 43 | return $this; 44 | } 45 | 46 | public function setClass($class) 47 | { 48 | $this->class = $class; 49 | return $this; 50 | } 51 | 52 | public function setType($type) 53 | { 54 | $this->type = $type; 55 | return $this; 56 | } 57 | 58 | public function setIcon($icon) 59 | { 60 | if (!Str::contains($icon, '<') && Str::contains($icon, 'fa')) { 61 | $icon = ""; 62 | } else if (!Str::contains($icon, '<')) { 63 | $data = [ 64 | 'name' => $icon, // Reemplaza con el nombre del icono 65 | 'class' => 'w-5 h-5', 66 | ]; 67 | $icon = Blade::render('', $data); 68 | } 69 | $this->icon = $icon; 70 | $this->generateText(); 71 | return $this; 72 | } 73 | 74 | public function setTitle($title) 75 | { 76 | parent::setTitle($title); 77 | $this->generateText(); 78 | return $this; 79 | } 80 | 81 | private function generateText() 82 | { 83 | $this->text = $this->icon.$this->title; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Texts/Heading.php: -------------------------------------------------------------------------------- 1 | render(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Texts/HorizontalDescription.php: -------------------------------------------------------------------------------- 1 | data = $this->title; 10 | } 11 | 12 | public function form() 13 | { 14 | $horizontal_description = $this; 15 | return view('front::texts.horizontal-description', compact('horizontal_description'))->render(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Texts/Paragraph.php: -------------------------------------------------------------------------------- 1 | render(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Texts/Table.php: -------------------------------------------------------------------------------- 1 | data = $this->title; 10 | if (isset($this->column) && is_array($this->column)) { 11 | $this->headers = $this->column; 12 | } 13 | if (!isset($this->headers)) { 14 | $this->headers = $this->detectHeaders(); 15 | } 16 | $this->orderData(); 17 | } 18 | 19 | protected function detectHeaders() 20 | { 21 | return collect($this->data)->collapse()->keys(); 22 | } 23 | 24 | protected function orderData() 25 | { 26 | $this->data = collect($this->data)->map(function ($item) { 27 | $row = []; 28 | foreach ($this->headers as $header) { 29 | $row[$header] = isset($item[$header]) ? $item[$header] : '--'; 30 | } 31 | return $row; 32 | }); 33 | } 34 | 35 | public function form() 36 | { 37 | $table = $this; 38 | return view('front::texts.table', compact('table'))->render(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Texts/Text.php: -------------------------------------------------------------------------------- 1 | form(); 16 | } 17 | 18 | public function showHtml($object) 19 | { 20 | return $this->formHtml(); 21 | } 22 | 23 | public function setText($text) 24 | { 25 | $this->text = $text; 26 | return $this; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Texts/Title.php: -------------------------------------------------------------------------------- 1 | render(); 13 | } 14 | 15 | public function setSize($size) 16 | { 17 | $this->size = $size; 18 | return $this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/ThumbManager.php: -------------------------------------------------------------------------------- 1 | validateWithCallable) && !$ignoreValidation) { 18 | $execute = ($this->validateWithCallable)($fullName); 19 | 20 | if (!$execute) { 21 | return $this->editThumb($fullName); 22 | } 23 | } 24 | 25 | $fullName = explode('/', $fullName); 26 | $key = count($fullName) - 1; 27 | 28 | $name = explode('.', $fullName[$key]); 29 | $name[0] = $name[0] . $prefix; 30 | $name = implode('.', $name); 31 | 32 | $fullName[$key] = $name; 33 | $fullName = implode('/', $fullName); 34 | 35 | return $this->editThumb($fullName); 36 | } 37 | 38 | protected function editThumb(string $name): string 39 | { 40 | if ($this->editWithCallable) { 41 | return ($this->editWithCallable)($name); 42 | } 43 | 44 | return $name; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Traits/HasActions.php: -------------------------------------------------------------------------------- 1 | index_actions()); 20 | if ($all) { 21 | $actions = collect($this->fields())->filter(function ($item) { 22 | return isset($item->actions) && count($item->actions) > 0; 23 | })->pluck('actions')->flatten(1)->merge($actions); 24 | } 25 | return $actions->map(function ($item) { 26 | if (is_string($item)) { 27 | return new $item(); 28 | } 29 | return $item; 30 | })->filter(function ($item) use ($all) { 31 | if ($all) { 32 | return true; 33 | } 34 | return $item->show && $item->show_button; 35 | })->map(function ($item) { 36 | return $item->addData($this->data); 37 | }); 38 | } 39 | 40 | public function getActions($all = false) 41 | { 42 | $actions = collect($this->actions()); 43 | if ($all) { 44 | $actions = collect($this->fields())->filter(function ($item) { 45 | return isset($item->actions) && count($item->actions) > 0; 46 | })->pluck('actions')->flatten(1)->merge($actions); 47 | } 48 | return $actions->map(function ($item) { 49 | if (is_string($item)) { 50 | return new $item(); 51 | } 52 | return $item; 53 | })->filter(function ($item) use ($all) { 54 | if ($all) { 55 | return true; 56 | } 57 | return $item->show && $item->show_button; 58 | })->map(function ($item) { 59 | return $item->addData($this->data); 60 | }); 61 | } 62 | 63 | public function searchIndexAction($slug) 64 | { 65 | return collect($this->getIndexActions(true))->filter(function ($item) use ($slug) { 66 | return $item->slug == $slug; 67 | })->first(); 68 | } 69 | 70 | public function searchAction($slug) 71 | { 72 | return collect($this->getActions(true))->filter(function ($item) use ($slug) { 73 | return $item->slug == $slug; 74 | })->first(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Traits/HasCards.php: -------------------------------------------------------------------------------- 1 | filters())->where('visible', true); 17 | } 18 | 19 | public function getFilters() 20 | { 21 | $search_filter = $this->getDefaultSearchFilter(); 22 | $filters = $this->filters(); 23 | $filters[] = new $search_filter(); 24 | return collect($filters)->filter(function ($item) { 25 | return $item->show; 26 | })->map(function ($item) { 27 | return $item->setResource($this); 28 | }); 29 | } 30 | 31 | public function getDefaultSearchFilter() 32 | { 33 | $default = $this->default_search_filter; 34 | if (!is_null($default)) { 35 | return $default; 36 | } 37 | return config('front.default_search_filter'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Traits/HasLenses.php: -------------------------------------------------------------------------------- 1 | addData($this->data)->setModel($this->getModel())->setSource($this->source); 22 | } 23 | // Or the slug name 24 | return collect($this->lenses())->filter(function ($item) use ($slug) { 25 | return $item->getLenseSlug() == $slug; 26 | })->map(function ($item) { 27 | return $item->addData($this->data)->setModel($this->getModel())->setSource($this->source)->setNormalFront($this); 28 | })->first(); 29 | } 30 | 31 | public function setNormalFront($front) 32 | { 33 | $this->normal_front = $front; 34 | return $this; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Traits/HasLinks.php: -------------------------------------------------------------------------------- 1 | getPageLinks(); 26 | } 27 | 28 | $links = []; 29 | 30 | // Show index actions 31 | $actions = $this->getActions()->filter(function ($item) use ($object) { 32 | return $item->hasPermissions($object); 33 | }); 34 | foreach ($actions as $action) { 35 | $links[] = Button::make($action->button_text)->addLink($this->getBaseUrl() . "/{$object->getKey()}/action/{$action->slug}"); 36 | } 37 | 38 | // Show links added manually 39 | foreach ($this->links() as $link => $text) { 40 | $links[] = Button::make($text)->addLink($link); 41 | } 42 | 43 | // Add delete button 44 | if ($this->canRemove($object)) { 45 | $links[] = Front::buttons()->getByName('delete', $this, $object); 46 | } 47 | 48 | // Add update button 49 | if ($this->canUpdate($object)) { 50 | $extraUrl = str_replace(request()->url(), '', request()->fullUrl()); 51 | $url = "{$this->getBaseUrl()}/{$object->getKey()}/edit{$extraUrl}"; 52 | $links[] = Front::buttons()->getByName('edit')->addLink($url); 53 | } 54 | 55 | return $links; 56 | } 57 | 58 | public function getIndexLinks() 59 | { 60 | $links = []; 61 | 62 | // Show index actions 63 | foreach ($this->getIndexActions() as $action) { 64 | $query = request()->fullUrl(); 65 | $query = explode('?', $query)[1] ?? ''; 66 | $query = strlen($query) > 0 ? '?' . $query : ''; 67 | $links[] = Button::make($action->button_text)->addLink($this->getBaseUrl() . "/action/{$action->slug}{$query}"); 68 | } 69 | 70 | // Show links added manually 71 | foreach ($this->index_links() as $link => $text) { 72 | $links[] = Button::make($text)->addLink($link); 73 | } 74 | 75 | // Show massive edition 76 | if ($this->enable_massive_edition) { 77 | $query = str_replace(url()->current(), '', url()->full()); 78 | $url = $this->getBaseUrl() . "/massive_edit" . $query; 79 | $links[] = Front::buttons()->getByName('edit')->addLink($url); 80 | } 81 | 82 | // Show create button 83 | if ($this->show_create_button_on_index && $this->canCreate()) { 84 | $url = $this->create_link; 85 | $url = str_replace('{base_url}', $this->getBaseUrl(), $url); 86 | $links[] = Front::buttons()->getByName('create')->setTitle(__('Create') . ' ' . $this->label)->addLink($url); 87 | } 88 | return $links; 89 | } 90 | 91 | public function getLenses() 92 | { 93 | $links = collect([]); 94 | 95 | // Show links to lenses 96 | if ($this->is_a_lense && isset($this->normal_front)) { 97 | $icon = isset($this->normal_front->icon) ? ' ' : ''; 98 | $title = $this->normal_front->lense_title ?? __('Normal View'); 99 | $text = $icon . $title; 100 | $links[] = Button::make($text)->addLink($this->getBaseUrl()); 101 | } else { 102 | $icon = isset($this->icon) ? ' ' : ''; 103 | $title = $this->lense_title ?? __('Normal View'); 104 | $text = $icon . $title; 105 | $links[] = Button::make($text)->addLink($this->getBaseUrl())->setClass('active'); 106 | } 107 | foreach ($this->lenses() as $lense) { 108 | $class = ''; 109 | if ($this->is_a_lense && $lense->getLenseSlug() == $this->getLenseSlug()) { 110 | $class = 'active'; 111 | } 112 | $icon = isset($lense->icon) ? ' ' : ''; 113 | $title = $lense->lense_title; 114 | $text = $icon . $title; 115 | $links[] = Button::make($text)->addLink($this->getBaseUrl() . "/lenses/{$lense->getLenseSlug()}")->setClass($class); 116 | } 117 | 118 | return $links; 119 | } 120 | 121 | public function getPageLinks() 122 | { 123 | $links = []; 124 | 125 | // Show links added manually 126 | foreach ($this->links() as $link => $text) { 127 | $links[] = Button::make($text)->addLink($link); 128 | } 129 | 130 | return $links; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Traits/HasMassiveEditions.php: -------------------------------------------------------------------------------- 1 | massive_class = $class; 23 | return $this; 24 | } 25 | 26 | public function enableMassive($value = true) 27 | { 28 | $this->show_massive = $value; 29 | return $this; 30 | } 31 | 32 | public function getFront() 33 | { 34 | return $this; 35 | } 36 | 37 | /* 38 | * Helpers 39 | */ 40 | 41 | public function getMassiveForms() 42 | { 43 | $forms = []; 44 | if (!isset($this->massive_class) || (isset($this->massive_class) && $this->massive_class->new_rows_available)) { 45 | $forms[] = Text::make(__('New rows'), 'rows'); 46 | } 47 | foreach (request()->except('rows') as $key => $value) { 48 | $forms[] = Hidden::make($key, $key)->setValue($value); 49 | } 50 | return $forms; 51 | } 52 | 53 | public function getTableHeadings($object = null) 54 | { 55 | // Always show ID column 56 | $headings = ['ID']; 57 | 58 | // Get front 59 | $front = $this->getFront(); 60 | if (!is_null($object)) { 61 | $front = $front->setObject($this->getResults($object)->first()); 62 | } 63 | 64 | // Show fields that are on index and that can be edited 65 | $fields = $front->indexFields()->filter(function ($item) { 66 | return $item->show_on_edit; 67 | }); 68 | 69 | // Save titles to the result 70 | foreach ($fields as $field) { 71 | $headings[] = $field->title; 72 | } 73 | $this->headings = $headings; 74 | 75 | // Return the headings 76 | return $headings; 77 | } 78 | 79 | public function getTableValues($object) 80 | { 81 | // Get front 82 | $front = $this->getFront()->setObject($object); 83 | 84 | // Get id value 85 | $id = is_a($object, 'Illuminate\Database\Eloquent\Model') ? $object->getKey() : $object->id; 86 | 87 | // Start the result with the id result 88 | $values = [$id]; 89 | 90 | // Show fields that are on index and that can be edited 91 | $fields = $front->indexFields()->filter(function ($item) { 92 | return $item->show_on_edit; 93 | }); 94 | 95 | // Save values to the result 96 | foreach ($fields as $field) { 97 | $column = $field->column; 98 | $field = $field->setColumn($id.'['.$field->column.']')->default($object->$column, true); 99 | if (get_class($field) == 'WeblaborMx\Front\Inputs\Number') { 100 | $field = $field->size(80); 101 | } 102 | $values[] = $field->form(); 103 | } 104 | 105 | // Return result 106 | return $values; 107 | } 108 | 109 | public function getExtraTableValues() 110 | { 111 | $result = []; 112 | $front = $this->getFront(); 113 | 114 | // Show fields that are on index and that can be created 115 | $fields = $front->indexFields()->filter(function ($item) { 116 | return $item->show_on_create; 117 | }); 118 | 119 | if (!isset($this->massive_class) || (isset($this->massive_class) && $this->massive_class->new_rows_available)) { 120 | for ($i = 0; $i < (request()->rows ?? 0); $i++) { 121 | $values = collect($this->headings)->flip()->map(function ($item) { 122 | return ''; 123 | }); 124 | foreach ($fields as $field) { 125 | $column = $field->column; 126 | $field = $field->setColumn('new'.$i.'['.$field->column.']'); 127 | if (get_class($field) == 'WeblaborMx\Front\Inputs\Number') { 128 | $field = $field->size(80); 129 | } 130 | $values[$field->title] = $field->form(); 131 | } 132 | $result[] = $values; 133 | } 134 | } 135 | return $result; 136 | } 137 | 138 | public function getTableButtons() 139 | { 140 | $buttons = []; 141 | if (isset($this->massive_class)) { 142 | foreach ($this->massive_class->buttons as $function => $title) { 143 | $buttons[$function] = $title; 144 | } 145 | } 146 | $buttons[null] = ' '.__('Save'); 147 | return $buttons; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/Traits/HasPermissions.php: -------------------------------------------------------------------------------- 1 | getModel()) && in_array('index', $this->actions); 12 | } 13 | 14 | public function canCreate() 15 | { 16 | return Gate::allows('create', $this->getModel()) && in_array('create', $this->actions); 17 | } 18 | 19 | public function canShow($object = null) 20 | { 21 | if (is_null($object)) { 22 | $object = $this->object; 23 | } 24 | return Gate::allows('view', $object) && in_array('show', $this->actions); 25 | } 26 | 27 | public function canUpdate($object = null) 28 | { 29 | if (is_null($object)) { 30 | $object = $this->object; 31 | } 32 | return Gate::allows('update', $object) && in_array('edit', $this->actions); 33 | } 34 | 35 | public function canRemove($object = null) 36 | { 37 | if (is_null($object)) { 38 | $object = $this->object; 39 | } 40 | return Gate::allows('delete', $object) && in_array('destroy', $this->actions); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/Traits/InputRelationship.php: -------------------------------------------------------------------------------- 1 | showOnHere()) { 33 | return $this; 34 | } 35 | $this->create_link_accessed = true; 36 | $this->create_link = is_callable($function) ? $function($this->create_link) : $function; 37 | $this->massive_edit_link = is_callable($function) ? $function($this->massive_edit_link) : $function; 38 | return $this; 39 | } 40 | 41 | public function addCreateLink($function) 42 | { 43 | if (!$this->showOnHere()) { 44 | return $this; 45 | } 46 | $this->add_create_link = is_callable($function) ? $function($this->create_link) : $function; 47 | return $this; 48 | } 49 | 50 | public function setMassiveEditLink($function) 51 | { 52 | $this->massive_edit_link = $function($this->massive_edit_link); 53 | return $this; 54 | } 55 | 56 | public function setEditLink($function) 57 | { 58 | if (!$this->showOnHere()) { 59 | return $this; 60 | } 61 | $this->edit_link_accessed = true; 62 | $this->edit_link = $function($this->edit_link); 63 | return $this; 64 | } 65 | 66 | public function setShowLink($function) 67 | { 68 | if (!$this->showOnHere()) { 69 | return $this; 70 | } 71 | $this->show_link_accessed = true; 72 | $this->show_link = $function($this->show_link); 73 | return $this; 74 | } 75 | 76 | public function with($with) 77 | { 78 | $this->with = $with; 79 | return $this; 80 | } 81 | 82 | public function hideCreateButton() 83 | { 84 | $this->create_link = null; 85 | return $this; 86 | } 87 | 88 | public function setRequest($request) 89 | { 90 | if (!$this->showOnHere()) { 91 | return $this; 92 | } 93 | request()->request->add($request); 94 | return $this; 95 | } 96 | 97 | // Filter on the query 98 | 99 | public function filterQuery($query) 100 | { 101 | $this->filter_query = $query; 102 | return $this; 103 | } 104 | 105 | // Filter on the collection, after the get() 106 | 107 | public function filterCollection($query) 108 | { 109 | $this->filter_collection = $query; 110 | return $this; 111 | } 112 | 113 | // Same that filterQuery but now dont access to the globalIndexQuery 114 | 115 | public function forceQuery($query) 116 | { 117 | $this->force_query = $query; 118 | return $this; 119 | } 120 | 121 | public function setLense($lense) 122 | { 123 | $this->lense = $lense; 124 | return $this; 125 | } 126 | 127 | public function hideColumns($hide_columns) 128 | { 129 | $this->hide_columns = $hide_columns; 130 | return $this; 131 | } 132 | 133 | public function setMassiveClass($class) 134 | { 135 | if (!is_null($class)) { 136 | $class = new $class(); 137 | } 138 | $this->massive_class = $class; 139 | return $this; 140 | } 141 | 142 | public function enableMassive($value = true) 143 | { 144 | $this->show_massive = $value; 145 | return $this; 146 | } 147 | 148 | public function blockEdition($block_edition = true) 149 | { 150 | $this->block_edition = $block_edition; 151 | return $this; 152 | } 153 | 154 | public function getFront() 155 | { 156 | return $this->front; 157 | } 158 | 159 | public function hideLink() 160 | { 161 | $this->hide_link = true; 162 | return $this; 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/Traits/InputRules.php: -------------------------------------------------------------------------------- 1 | rules = $rules; 14 | return $this; 15 | } 16 | 17 | public function creationRules($rules) 18 | { 19 | $this->creation_rules = $rules; 20 | return $this; 21 | } 22 | 23 | public function updateRules($rules) 24 | { 25 | $this->update_rules = $rules; 26 | return $this; 27 | } 28 | 29 | public function getRules($source = 'store') 30 | { 31 | $rules = $this->rulesAsArray(); 32 | 33 | if ($source == 'update' && isset($this->update_rules)) { 34 | $extra_rules = $this->update_rules; 35 | } elseif ($source == 'store' && isset($this->creation_rules)) { 36 | $extra_rules = $this->creation_rules; 37 | } 38 | 39 | if (isset($extra_rules)) { 40 | $extra_rules = is_string($extra_rules) ? [$extra_rules] : $extra_rules; 41 | $rules = array_merge($rules, $extra_rules); 42 | } 43 | 44 | if (!$this->validateConditional(request())) { 45 | return []; 46 | } 47 | 48 | return $rules; 49 | } 50 | 51 | /* ---------- 52 | * Helpers 53 | ------------ */ 54 | 55 | public function required() 56 | { 57 | $this->rules = $this->rulesAsArray(); 58 | $this->rules[] = 'required'; 59 | return $this; 60 | } 61 | 62 | /** @internal */ 63 | private function rulesAsArray(): array 64 | { 65 | $rules = $this->rules ?? []; 66 | $rules = is_string($rules) ? [$rules] : $rules; 67 | return $rules; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Traits/InputVisibility.php: -------------------------------------------------------------------------------- 1 | show_on_index = false; 17 | return $this; 18 | } 19 | 20 | public function hideFromDetail() 21 | { 22 | $this->show_on_show = false; 23 | return $this; 24 | } 25 | 26 | public function hideWhenCreating() 27 | { 28 | $this->show_on_create = false; 29 | return $this; 30 | } 31 | 32 | public function hideWhenUpdating() 33 | { 34 | $this->show_on_edit = false; 35 | return $this; 36 | } 37 | 38 | public function onlyOnIndex() 39 | { 40 | $this->show_on_index = true; 41 | $this->show_on_show = false; 42 | $this->show_on_edit = false; 43 | $this->show_on_create = false; 44 | return $this; 45 | } 46 | 47 | public function onlyOnDetail() 48 | { 49 | $this->show_on_index = false; 50 | $this->show_on_show = true; 51 | $this->show_on_edit = false; 52 | $this->show_on_create = false; 53 | return $this; 54 | } 55 | 56 | public function onlyOnCreate() 57 | { 58 | $this->show_on_index = false; 59 | $this->show_on_show = false; 60 | $this->show_on_edit = false; 61 | $this->show_on_create = true; 62 | return $this; 63 | } 64 | 65 | public function onlyOnEdit() 66 | { 67 | $this->show_on_index = false; 68 | $this->show_on_show = false; 69 | $this->show_on_edit = true; 70 | $this->show_on_create = false; 71 | return $this; 72 | } 73 | 74 | public function onlyOnForms() 75 | { 76 | $this->show_on_index = false; 77 | $this->show_on_show = false; 78 | $this->show_on_edit = true; 79 | $this->show_on_create = true; 80 | return $this; 81 | } 82 | 83 | public function exceptOnForms() 84 | { 85 | $this->show_on_index = true; 86 | $this->show_on_show = true; 87 | $this->show_on_edit = false; 88 | $this->show_on_create = false; 89 | return $this; 90 | } 91 | 92 | public function show($result) 93 | { 94 | if (!is_string($result) && is_callable($result)) { 95 | $result = $result(); 96 | } 97 | $this->show = $result; 98 | return $this; 99 | } 100 | 101 | public function shouldBeShown() 102 | { 103 | return $this->show && $this->show_before; 104 | } 105 | 106 | public function showOnHere() 107 | { 108 | $var = $this->source ?? 'index'; 109 | $var = $var == 'update' ? 'edit' : $var; 110 | $var = $var == 'store' ? 'create' : $var; 111 | $var = 'show_on_' . $var; 112 | return $this->$var && $this->shouldBeShown(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/Traits/InputWithActions.php: -------------------------------------------------------------------------------- 1 | actions = $actions; 12 | return $this; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Traits/InputWithLinks.php: -------------------------------------------------------------------------------- 1 | create_button_title = $title; 17 | return $this; 18 | } 19 | 20 | public function addLinks($links) 21 | { 22 | if (!$this->showOnHere()) { 23 | return $this; 24 | } 25 | if (!is_string($links) && is_callable($links)) { 26 | $links = $links(); 27 | } 28 | $this->links = $links; 29 | return $this; 30 | } 31 | 32 | public function getLinks($object, $key, $front) 33 | { 34 | $links = []; 35 | $can_edit = !isset($this->block_edition) || !$this->block_edition; 36 | 37 | // Add actions links 38 | if (isset($this->actions) && count($this->actions) > 0) { 39 | foreach ($this->actions as $action) { 40 | $url = "{$this->front->getBaseUrl()}/{$object->getKey()}/action/{$action->slug}"; 41 | $links[] = Button::make($action->button_text)->addLink($url); 42 | } 43 | } 44 | 45 | // Show links added manually 46 | foreach ($this->links as $link => $text) { 47 | $links[] = Button::make($text)->addLink($link); 48 | } 49 | 50 | // Add massive edit link 51 | if (isset($this->massive_edit_link) && $this->show_massive && $can_edit) { 52 | $extra_query = http_build_query(request()->all()); 53 | if (strlen($extra_query) > 0) { 54 | $extra_query = '&' . $extra_query; 55 | } 56 | $url = "{$front->getBaseUrl()}/{$object->getKey()}/massive_edit/{$key}{$this->massive_edit_link}{$extra_query}"; 57 | $links[] = Front::buttons()->getByName('edit')->addLink($url)->setTitle(__('Edit') . " {$this->front->plural_label}"); 58 | } 59 | 60 | // Add create link 61 | if (isset($this->create_link) && strlen($this->create_link) > 0 && $this->front->canCreate() && $can_edit) { 62 | $title = Str::singular($this->title) ?? $this->front->label; 63 | $title = $this->create_button_title ?? __('Add') . " {$title}"; 64 | $links[] = Front::buttons()->getByName('create')->addLink($this->create_link)->setTitle($title); 65 | } 66 | 67 | return $links; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Traits/IsALense.php: -------------------------------------------------------------------------------- 1 | lense_slug)) { 15 | return $this->lense_slug; 16 | } 17 | return class_basename(get_class($this)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Traits/IsRunable.php: -------------------------------------------------------------------------------- 1 | handle(); 12 | } 13 | 14 | public function isFrontable($result) 15 | { 16 | if (!is_array($result)) { 17 | return false; 18 | } 19 | $result = collect($result)->map(function ($item) { 20 | return get_class($item); 21 | }); 22 | return $result->contains(function ($item) { 23 | return Str::contains($item, 'WeblaborMx\Front'); 24 | }); 25 | } 26 | 27 | public function makeFrontable($result, $setters, $front) 28 | { 29 | $page_class = 'WeblaborMx\Front\Pages\Page'; 30 | if (class_exists('App\Front\Pages\Page')) { 31 | $page_class = 'App\Front\Pages\Page'; 32 | } 33 | 34 | // Get page 35 | $page = (new $page_class())->setSource('index')->setFields($result); 36 | foreach ($setters as $key => $value) { 37 | $page->$key = $value . ' - ' . __('Result'); 38 | } 39 | 40 | // Get variables to pass 41 | $fields = $this->getParameters(compact('front', 'page')); 42 | 43 | return view($page->view, $fields); 44 | } 45 | 46 | /* 47 | * Controller Internal Functions 48 | */ 49 | 50 | private function getObject($object) 51 | { 52 | $model = $this->front->getModel(); 53 | $object = $model::find($object); 54 | if (!is_object($object)) { 55 | abort(404); 56 | } 57 | return $object; 58 | } 59 | 60 | private function getParameters($array = [], $object = false) 61 | { 62 | $parameters = request()->route()->parameters(); 63 | $return = collect($parameters)->merge($array)->all(); 64 | if ($object) { 65 | return (object) $return; 66 | } 67 | return $return; 68 | } 69 | 70 | public function getParameter($name = 'object') 71 | { 72 | return request()->route()->parameters()['front_' . $name]; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Traits/IsValidated.php: -------------------------------------------------------------------------------- 1 | source == 'store' ? 'create' : 'edit'; 12 | } 13 | 14 | // Get fields 15 | $fields = collect($this->filterFields($source, true))->filter(function ($item) { 16 | return $item->shouldBeShown(); 17 | }); 18 | 19 | // Get rules on inputs of the resource 20 | $rules = $fields->filter(function ($item) { 21 | return count($item->getRules($this->source)) > 0; 22 | })->map(function ($item) { 23 | return $item->setResource($this); 24 | })->mapWithKeys(function ($item) { 25 | return [$this->validatorGetColumn($item->column) => $item->getRules($this->source)]; 26 | })->all(); 27 | return $rules; 28 | } 29 | 30 | 31 | public function makeValidation($data) 32 | { 33 | // Get fields 34 | $fields = collect($this->filterFields($this->source == 'store' ? 'create' : 'edit', true))->filter(function ($item) { 35 | return $item->shouldBeShown(); 36 | }); 37 | 38 | // Get rules on inputs of the resource 39 | $rules = $this->getRules(); 40 | 41 | // Update rules on inputs 42 | foreach ($fields as $field) { 43 | $rules = $field->editRules($rules); 44 | } 45 | 46 | // Execute validator function on fields 47 | $fields->map(function ($item) { 48 | return $item->setResource($this); 49 | })->each(function ($item) use ($data) { 50 | return $item->validate($data); 51 | }); 52 | 53 | // Validate all the rules 54 | $attributes = $fields->filter(function ($item) { 55 | return isset($item->column) && isset($item->title) && is_string($item->column) && is_string($item->title); 56 | })->mapWithKeys(function ($item) { 57 | return [$this->validatorGetColumn($item->column) => $item->title]; 58 | })->toArray(); 59 | 60 | \Validator::make($data, $rules, [], $attributes)->validate(); 61 | } 62 | 63 | private function validatorGetColumn($column) 64 | { 65 | $column = str_replace('[', '.', $column); 66 | $column = str_replace(']', '', $column); 67 | $column = trim($column, '.'); 68 | return __($column); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Traits/ResourceHelpers.php: -------------------------------------------------------------------------------- 1 | show_title && $this->source == 'show') { 13 | $view_title_field = $this->view_title; 14 | return $object->$view_title_field; 15 | } 16 | if ($this->show_title) { 17 | $view_title_field = $this->title; 18 | return $object->$view_title_field; 19 | } 20 | return __($this->label); 21 | } 22 | 23 | public function getPartialIndexHelper($result, $page_name, $show_filters) 24 | { 25 | return new PartialIndex($this, $result, $page_name, $show_filters); 26 | } 27 | 28 | public function getActionsHelper($object, $base_url, $edit_link, $show_link) 29 | { 30 | return new Actions($this, $object, $base_url, $edit_link, $show_link); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Traits/Sourceable.php: -------------------------------------------------------------------------------- 1 | source = $source; 12 | session()->put('source', $source, now()->addMinute()); 13 | return $this; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Traits/WithWidth.php: -------------------------------------------------------------------------------- 1 | width, '/')) { 14 | $width = explode('/', $this->width); 15 | return round((12 / $width[1]) * $width[0]); 16 | } 17 | return 12; 18 | } 19 | 20 | public function style_width() 21 | { 22 | if ($this->width == 'full') { 23 | return "width: 100%"; 24 | } 25 | return "width: calc({$this->width_porcentage()}% - 25px); display: inline-block; vertical-align:top; margin: 20px 10px;"; 26 | } 27 | 28 | public function width_porcentage() 29 | { 30 | if (Str::contains($this->width, '/')) { 31 | $width = explode('/', $this->width); 32 | return round((100 / $width[1]) * $width[0]); 33 | } 34 | return 100; 35 | } 36 | 37 | public function setWidth($width) 38 | { 39 | $this->width = $width; 40 | return $this; 41 | } 42 | 43 | public function html() 44 | { 45 | $input = $this; 46 | $value = $this->form(); 47 | return view('front::input-outer', compact('value', 'input'))->render(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Workers/FrontStore.php: -------------------------------------------------------------------------------- 1 | authorize('create', $this->front->getModel()); 18 | $front = $this->front->setSource('store'); 19 | if (isset($this->lense)) { 20 | $front = $front->getLense($this->lense); 21 | } 22 | return $this->run(new Job(request(), $front)); 23 | } 24 | 25 | public function setLense($lense) 26 | { 27 | $this->lense = $lense; 28 | return $this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Workers/Worker.php: -------------------------------------------------------------------------------- 1 | source = $source; 19 | $this->front = Front::makeResource($front, $this->source); 20 | } 21 | 22 | public static function make($title = null, $column = null, $extra = null) 23 | { 24 | $source = session('source'); 25 | return new static($title, $column, $extra, $source); 26 | } 27 | 28 | public function handle() 29 | { 30 | // 31 | } 32 | 33 | public function execute() 34 | { 35 | try { 36 | return $this->handle(); 37 | } catch (ValidationException $e) { 38 | return collect($e->errors())->flatten(1)->implode('
    '); 39 | } catch (\Exception $e) { 40 | return $e->getMessage(); 41 | } 42 | } 43 | } 44 | --------------------------------------------------------------------------------