Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 Re: Laravel 5.x » Преобразовать массив в многомерный » 13.06.2020 22:30:18

Меня всегда поражали люди, которые сами себе создают трудности затем, чтобы их в последствии героически преодолевать.

Возможно, так происходит у новичков, кем я и являюсь. Реализую работу на том уровне, на котором могу на данный момент. А поразиться или  удивиться - это был Ваш выбор и Вы его сделали.

Ведь очевидно, что image1 и image_description1 это какие-то поля ввода, автоматически генерируемые на форме с помощью js, так что мешает сразу оформить их как надо?

Не очевидно. У меня форма статична. Но за наводку спасибо.

#2 Laravel 5.x » Преобразовать массив в многомерный » 12.06.2020 00:25:15

Wincor
Ответов: 2

Версия  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] как-то топорно.

#3 Re: Laravel 5.x » Помогите реализовать связанные списки с помощью функции jQuery ajax. » 07.06.2020 13:31:18

В прошлом году мне помогла вот эта статья.

Надеюсь, он наведет Вас на мысль и поможет в реализации.

#4 Re: Laravel 5.x » Ошибка TokenMismatchException in VerifyCsrfToken.php line 68: » 23.10.2019 17:02:11

Версия  Laravel Framework 5.4.36
Версия PHP 7.1.22
Windows 7 x64

Просто мистика какая-то. Вчера все было ок. Хотя, не совсем, редко, но появлялась ошибка  Ошибка TokenMismatchException in VerifyCsrfToken.php line 68 и как у Vladimir_user после обновления страницы все становилось ок. Сегодня, при нажатии кнопки в любой форме любого вида любой модели появляется эта ошибка! sad

Куки включены, мета тег в шапке 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 . '  содержит подкатегории!');
    }
}

Прошу помощи. Если есть необходимость, могу выставить на диск весь проект.

#5 Re: Laravel 5.x » Помогите реализовать связанные списки с помощью функции jQuery ajax. » 12.10.2019 19:44:58

Ошибку 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">

#6 Laravel 5.x » Помогите реализовать связанные списки с помощью функции jQuery ajax. » 12.10.2019 16:45:36

Wincor
Ответов: 2

Версия  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>

Подвал раздела