Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Меня всегда поражали люди, которые сами себе создают трудности затем, чтобы их в последствии героически преодолевать.
Возможно, так происходит у новичков, кем я и являюсь. Реализую работу на том уровне, на котором могу на данный момент. А поразиться или удивиться - это был Ваш выбор и Вы его сделали.
Ведь очевидно, что image1 и image_description1 это какие-то поля ввода, автоматически генерируемые на форме с помощью js, так что мешает сразу оформить их как надо?
Не очевидно. У меня форма статична. Но за наводку спасибо.
Версия Laravel Framework 5.4.36
Версия PHP 7.1.22
Windows 7 x64
OpenServer
В контроллере метод store принимает данные из формы. Есть массив:
array:9 [▼
"title" => "объект"
"description" => "описание"
"property" => "свойство"
"image_description1" => "описание изображения1"
"image_description2" => "описание изображения2"
"image_description3" => "описание изображения3"
"image1" => UploadedFile {#172 ▶}
"image2" => UploadedFile {#175 ▶}
"image3" => UploadedFile {#175 ▶}
]
Каким методом или их комбинацией вытащить из данного массива его часть по маске ключа, например image и получить
array:6 [▼
"image_description1" => "описание изображения1"
"image_description2" => "описание изображения2"
"image_description3" => "описание изображения3"
"image1" => UploadedFile {#172 ▶}
"image2" => UploadedFile {#175 ▶}
"image3" => UploadedFile {#175 ▶}
]
а затем преобразовать в массив вида:
array:3 [▼
0 => array:2 [▼
"image1" => UploadedFile {#172 ▶}
"image_description1" => "описание изображения1"
]
1 => array:2 [▼
"image2" => UploadedFile {#175 ▶}
"image_description2" => "описание изображения2"
]
2 => array:2 [▼
image3" => UploadedFile {#175 ▶}
"image_description3" => "описание изображения3"
]
]
Пробовал через метод only(), но получается громоздко
$filtered1 = $request->only(['image1', 'image_description1']);
$filtered2 = $request->only(['image2', 'image_description2']);
$filtered3 = $request->only(['image3', 'image_description3']);
да и опять останавливаюсь перед той же задачей, так как вариант $result = [$filtered1, $filtered2, $filtered3] как-то топорно.
Версия Laravel Framework 5.4.36
Версия PHP 7.1.22
Windows 7 x64
Просто мистика какая-то. Вчера все было ок. Хотя, не совсем, редко, но появлялась ошибка Ошибка TokenMismatchException in VerifyCsrfToken.php line 68 и как у Vladimir_user после обновления страницы все становилось ок. Сегодня, при нажатии кнопки в любой форме любого вида любой модели появляется эта ошибка!
Куки включены, мета тег в шапке html файла есть, подключен Collective\Html\HtmlServiceProvider и он генерирует токен в форме в виде скрытого input, прописывал даже {{ csrf_field() }}, в просмотре кода видно что есть два поля
<input name="_token" type="hidden" value="7Sy8yPBr2ECAVKFtgMpYNZurYi4hv5tz3RM4d3aU">
Не помогло и исключить URI из-под CSRF-защиты
Вид (создание категории)
<div class="box">
{!! Form::open(['route' => 'categories.store']) !!}
{{ csrf_field() }}
<div class="box-header with-border">
<h3 class="box-title">Добавить новую категорию</h3>
</div>
@include('admin.errors')
<div class="box-body">
<div class="col-md-6">
<div class="form-group">
<label for="exampleInputEmail1">Название</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="" name="title" value="{{old('title')}}">
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer box-footer-border-top">
<!-- <button class="btn btn-default">Назад</button>-->
<button class="btn btn-success pull-right">Добавить</button>
</div>
<!-- /.box-footer-->
{!! Form::close() !!}
</div>
Роуты
Route::post('admin/products/create', 'Admin\ProductsController@list')->name('products.list');
Route::group(['prefix'=>'admin', 'namespace' => 'Admin'], function(){
Route::get('/', 'DashBoardController@index');
Route::resource('/categories', 'CategoriesController');
Route::resource('/subcategories', 'SubcategoriesController');
Route::resource('/tags', 'TagsController');
//Route::resource('/users', 'UsersController');
Route::resource('/products', 'ProductsController');
Route::resource('/brands', 'BrandsController');
Route::resource('/linemodels', 'LineModelsController');
});
Модель
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Category extends Model
{
use Sluggable;
protected $fillable = ['title'];
public function products()
{
return $this->hasMany(Product::class);
}
public function subcategories()
{
return $this->hasMany(SubCategory::class);
}
public function brands()
{
return $this->hasMany(Brand::class);
}
public function linemodel()
{
return $this->hasMany(Linemodel::class);
}
public function sluggable()
{
return [
'slug'=> [
'source'=>'title'
]
];
}
}
Контроллер
<?php
namespace App\Http\Controllers\Admin;
use Validator;
use App\Category;
use App\Http\Controllers\Controller;
use App\Http\Requests\CategoryRequest;
use Illuminate\Http\Request;
use Illuminate\Foundation\Http\FormRequest;
class CategoriesController extends Controller
{
public function index()
{
$categories = Category::all();
return view('admin.categories.index',
[
'categories' => $categories,
]);
}
public function create()
{
return view('admin.categories.create');
}
//public function store(Request $request)
public function store(CategoryRequest $request)
{
return redirect()->route('categories.create');
}
public function edit($id)
{
$category = Category::find($id);
return view('admin.categories.edit', [
'category' => $category,
]);
}
public function update(CategoryRequest $request, $id)
{
$category = Category::find($id);
$category->update($request->all());
return redirect()->route('categories.index');
}
public function destroy($id)
{
$category = Category::find($id);
if($category->subcategories->isEmpty())
{
$category->delete();
return redirect()->route('categories.index');
}
return redirect()->route('categories.index')->with('message','Нельзя удалить! Категория ' . $category->title . ' содержит подкатегории!');
}
}
Прошу помощи. Если есть необходимость, могу выставить на диск весь проект.
Ошибку 404 (Not Found) поборол, указав корректный URL в скрипте:
было
url: '/products/create'
стало
url: '/admin/products/create'
Но появилась ошибка 500 (Internal Server Error) в Laravel - TokenMismatchException. Добавил в html страницу
<meta name="csrf-token" content="{{ csrf_token() }}"/>
а в скрипт
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
странно, ведь подключен Collective\Html\HtmlServiceProvider и он генерирует токен в форме в виде скрытого input
<input name="_token" type="hidden" value="IvypXaU0u4HmsvgLPsB5CfbzlICmAcltTTFvXFpE">
Версия Laravel Framework 5.4.36
Версия PHP 7.1.22
Windows 7 x64
OpenServer
Техническое задание:
Реализовать связанные выпадающие списки с помощью функции jQuery ajax. Есть форма с двумя элементами выпадающих списков Категорий и Подкатегорий. Список Подкатегории неактивный и пустой. При выборе категории список Подкатегории должен стать активным и иметь список подкатегорий соответствующих родительской категории.
Что произошло:
При выборе категории сразу же появляется ошибка (смотрю в консоле)
POST http://redcat/product/create 404 (Not Found)
и в Network-> Preview
NotFoundHttpException
Получается, не найден роут для данного URI и на сервер не отправляется запрос.
Возможно, синтаксис роутов с ошибкой или в скрипте. Как ни проверял/пробовал разные варианты – все никак. Или не совсем понимаю маршрутизацию. Помогите разобраться.
Код:
Routes:
Route::post('admin/products/create', 'Admin\ProductsController@list')->name('products.list');
Route::group(['prefix'=>'admin', 'namespace' => 'Admin'], function(){
Route::get('/', 'DashBoardController@index');
Route::resource('/categories', 'CategoriesController');
Route::resource('/subcategories', 'SubcategoriesController');
//Route::resource('/tags', 'TagsController');
//Route::resource('/users', 'UsersController');
Route::resource('/products', 'ProductsController');
Route::resource('/brands', 'BrandsController');
Route::resource('/linemodels', 'LineModelsController');
});т
app\Http\Controllers\ProductsController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Product;
use App\Tag;
use App\Category;
use App\Subcategory;
use App\Brand;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
class ProductsController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$products = Product::all();
return view('admin.products.index', compact(
'products'
));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function list(Request $request)
{
dd($request->all());
return view('admin.products.create');
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$categories = Category::pluck('title', 'id')->all();
$subcategories = Subcategory::pluck('title', 'id')->all();
$brands = Brand::pluck('title', 'id')->all();
return view('admin.products.create', compact(
'categories',
'subcategories',
'brands'
));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// $selectcategory = (int)$_POST['category'];
// dd($_POST);
$this->validate($request, [
'title' => 'required',
//'price' => 'required|regex:/^\d{0,8}(\.\d{1,2})?$/',
'category_id' => 'required',
'subcategory_id' => 'required',
'brand_id' => 'required',
/* 'content' => 'required',
'date' => 'required',
'image' => 'nullable|image'*/
]);
// $price = $request->price;
// $price = $price*2;
$product = Product::add($request->all());
/* $product->uploadImageProduct($request->file('image'));
$product->setCategory($request->get('category_id'));
$product->setTags($request->get('tags'));
$product->statusToggle($request->get('status'));
$product->availableToggle($request->get('available'));
$product->toggleFeatured($request->get('is_featured'));
*/
// dd($request->all());
return redirect()->route('products.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$product = Product::find($id);
return view('admin.products.edit', compact(
'product'
));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'title' => 'required',
'price' => 'required|regex:/^\d{0,8}(\.\d{1,2})?$/'
]);
$product = Product::find($id);
$product->edit($request->all());
return redirect()->route('products.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
Product::find($id)->remove();
return redirect()->route('products.index');
}
app\Models\Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Support\Fasades\Storage;
class Product extends Model
{
use Sluggable;
protected $fillable = ['title','price','category_id','subcategory_id','brand_id'];
public function category()
{
return $this->belongsTo(Category::class);
}
public function subcategory()
{
return $this->belongsTo(Subcategory::class);
}
/*
public function brand()
{
return $this->hasOne(Brand::class);
}
public function linemodel()
{
return $this->hasOne(Linemodel::class);
}
*/
public static function add($fields)
{
$product = new static;
$product->fill($fields);
$product->save();
return $product;
}
public function edit($fields)
{
$this->fill($fields);
$this->save();
}
public function remove()
{
$this->delete();
}
public function setCategory($id)
{
if($id == null) {return;}
$category = Category::find($id);
$this->category()->save($category);
/*
$this->category_id = $id;
$this->save();
*/
}
public function setSubcategory($id)
{
if($id == null) {return;}
$subcategory = Subcategory::find($id);
$this->subcategory()->save($subcategory);
/*
$this->category_id = $id;
$this->save();
*/
}
public function getListSubcategoryById()
{
$selectcategory = (int)$_POST['category'];
return $selectcategory;
}
public function sluggable()
{
return [
'slug'=> [
'source'=>'title'
]
];
}
}
app\Models\Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Category extends Model
{
use Sluggable;
protected $fillable = ['title'];
public function products()
{
return $this->hasMany(Product::class);
}
public function subcategories()
{
return $this->hasMany(SubCategory::class);
}
public function brands()
{
return $this->hasMany(Brand::class);
}
public function linemodel()
{
return $this->hasMany(Linemodel::class);
}
public function sluggable()
{
return [
'slug'=> [
'source'=>'title'
]
];
}
}
app\Models\Subcategory.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Subcategory extends Model
{
use Sluggable;
protected $fillable = ['title', 'category_id'];
public function products()
{
return $this->hasMany(Product::class);
}
public function brands()
{
return $this->belongsToMany(
Brand::class,
'subcategory_brand',
'subcategory_id',
'brand_id'
);
}
public function category()
{
return $this->belongsTo(Category::class);
}
public function linemodel()
{
return $this->hasMany(Linemodel::class);
}
public function sluggable()
{
return [
'slug'=> [
'source'=>'title'
]
];
}
}
script:
$(document).ready(function () {
$('#category').change(function(){
var category_id = parseInt($('#category').val());
console.log(category_id);
selectSubcategory(category_id);
});
});
function selectSubcategory(id){
var subcat = $('#category');
console.log(id);
if(id > 0){
subcat.prop('disabled', false);
$.ajax({
url: '/products/create',
type: 'POST',
data: 'id',
success: function(){
alert('Данные ушли!');
},
/*error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
}*/
});
}
}
resources/views/admin/products/create.blade.php :
<div class="form-group">
<label>Категория <span class="star">*</span></label>
{{Form::select(
'category_id',
$categories,
null,
[
'class' => 'form-control select2',
'placeholder'=>'Выбирете категорию',
'id'=>'category',
])
}}
</div>
<div class="form-group">
<label>Подкатегория <span class="star">*</span></label>
{{Form::select(
'subcategory_id',
[],
null,
[
'class' => 'form-control select2 ',
'placeholder'=>'Выбирете подкатегорию',
'id'=>'subcategory',
'disabled'=> true,
])
}}
</div>