Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
При отображении пройдись по $array_symbols_id с помощью foreach() и отображай картинки через что-то вроде $array_images->where('photo_symbol_id', $array_symbols_id[4])->first()->photo_src
говорят, запросы по циклу в базу слать не есть хорошо
На вход поступает массив из ID символов. И таким запросом получаю картинки, которые соответствуют этим символам
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->where('photo_moderation_id','2')
->orderByRaw('RAND()')
->get(['photo_id', 'photo_src', 'photo_symbol_id']);
Но в случае, если символы дублируются, то запрос отдает только 1 картинку.
Пример: если ввожу в инпут "фыв" то массив входных символов такой
array:3 [
0 => "28"
1 => "21"
2 => "3"
и получаю 3 картинки, соотвествующие этим символам.
Но если ввожу фразу "фывфыв", получаю массив
array:6 [
0 => "28"
1 => "21"
2 => "3"
3 => "21"
4 => "28"
5 => "3"
]
то в итоге получаю опять же те три картинки, а мне надо что бы они вывелись по два раза
простых путей мы не ищем. любим помучать и себя и начальство и соседей.
->toArray() кстати не работает, ловлю Exception call to a member function toArray() on array l
так а как решить проблему с дубляцией?
и, собственно, со сборкой массива
и после преведения запроса к такому виду
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->where('photo_moderation_id','2')
->orderByRaw('RAND()')
->select('photo_src', 'photo_symbol_id', 'photo_id')
->get();
выбираются все фото, у которых symbol_id одинаковый.
например ввожу фыв! и получаю две фотки со связанным символом восклицательного знака
foreach не прокатит, т.к. всегда в разной последовательности база отдает символы, а мне нужно их выстроить именно в той, в которой они были введены. до того, как понадобилось выводить ID фото это было сделано вот так
$array_images = array_map(function($key) use($array_images){
return array(
"ID" => $key,
"SRC" => $array_images[$key]
);
}, $array_symbols_id);
Не совсем понятно. Тебе массив нужен с тремя полями вместо двух? И напиши пожалуйста подробнее зачем тебе массив (для select или чего-то еще?), тогда, возможно, найдется элегантное решение.
в input вводится текст, этот текст разбивается посимвольно. Каждый символ имеет свой ID. Есть таблица фото, где одно фото связано с одним символом по ID.
этот запрос как раз и выдергивает фото, используя нужные символы
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->where('photo_moderation_id','2')
->orderByRaw('RAND()')
->lists('photo_src', 'photo_symbol_id');
в итоге получаю такой массив
array:4 [
33 => "/img/1479213661вск.png"
28 => "/img/Ы.png"
3 => "/img/В.png"
21 => "/img/Ф.png"
]
где ключ - это ID символа,а значение - собственно сама фотка.
проблема в том, что когда изображение создано, юзер может заменить некоторые символы, кликая по нужным фоткам. Для того что бы понять, какую фотку нужно заменить я должен знать ID фото, которую хотят заменить. Именно поэтому мне нужен массив вида
array:4 [
33 => array('photo_id' => 2, 'src' => "/img/1479213661вск.png"),
28 => array('photo_id' => 3, 'src' => "/img/Ы.png"),
3 => array('photo_id' => 4, 'src' => "/img/В.png"),
21 => array('photo_id' => 5, 'src' => "/img/Ф.png"),
]
добавь ->select('field','field2')
и ->get() вместо ->lists()
но при этом ты теряешь массив и получаешь объект, с которым можно работать (читай Collections)
а что если мне массив нужен?
есть вот такой запрос
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->where('photo_moderation_id','2')
->orderByRaw('RAND()')
->lists('photo_src', 'photo_symbol_id');
на выходе получаю массив
array:4 [
33 => "/img/1479213661вск.png"
28 => "/img/Ы.png"
3 => "/img/В.png"
21 => "/img/Ф.png"
]
где ключ - это photo_symbol_id, Значение - это photo_src
как изменить запрос что бы добавить к результату еще поле photo_id ?
}%> Тогда через что-то вроде %%orderByRaw('RAND()')->take(1)%% делать.
Если бы я был **hzone**, я бы сказал, что за такое увольняют.Пока у тебя там 100 записей на все таблицы - это работает. А когда у тебя тысячи или миллионы (фотографий столько вполне может быть)... Что оно делает? Читает (full scan) всю таблицу от записи 0 до записи 1,000,000, что обычно приводит к созданию таблицы на диске в несколько гигов. И только потом возвращает, сколько там, одну запись?
эм...но у меня же записи отбираются по условию
whereIn('photo_symbol_id', $array_symbols_id)
и уже из них делается рандом
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->where('photo_moderation_id','2')
->orderByRaw('RAND()')
->lists('photo_src', 'photo_symbol_id');
вот так помогло. спасибо!
respectpick пишет:при вызове inRandomOrder() получаю Call to undefined method Illuminate\Database\Query\Builder::inRandomOrder()
и версия laravel у меня 5.0.35
Да, эта функция в 5.2 и выше. Тогда через что-то вроде orderByRaw('RAND()')->take(1) делать.
а как это присоединить к моему запросу?
Если я правильно тебя понял, то ты можешь использовать inRandomOrder()->first() или, если тебе нужен `lists()`, то take(1):
$array_images = DB::table('photo') ->whereIn('photo_symbol_id', $array_symbols_id) ->inRandomOrder() ->take(1) ->pluck('photo_src', 'photo_symbol_id');
И еще, не используй lists(), он был давно deprecated и его убрали в 5.3. Используй pluck(), поможет в будущем легче проапгрейдить проект.
при вызове inRandomOrder() получаю Call to undefined method Illuminate\Database\Query\Builder::inRandomOrder()
и версия laravel у меня 5.0.35
есть текстовый инпут в который вводится любой текст, далее строка разбивается посимвольно. каждый символ имеет свой ID. например при вводе в инпут текста "фыв!"
входной массив $array_symbols_id выглядит так
array:4 [
0 => "21"
1 => "28"
2 => "3"
3 => "33"
]
далее таким образом из БД выбираются нужные изображения - соотвествующие этим символам
$array_images = DB::table('photo')
->whereIn('photo_symbol_id', $array_symbols_id)
->lists('photo_src', 'photo_symbol_id');
допустим у меня есть символ ! (восклицательный знак). Я загружаю в таблицу фото и устанавливаю связь, что это фото связано с символом ! имеющим ID 33.
пока такое фото одно в таблице все нормально, оно и будет всегда выбираться. Проблема наступает тогда, когда я загружу еще несколько фото восклицательных знаков. т.е. при вводе фыв! я буду всегда на место восклицательного знака получать последнее загруженное фото, а мне нужно выбрать случайное значение из всех фото, связных с символом !
Вопрос - что дописать в запрос что бы выборка была рандомной?
версия Laravel 5.0.35
народ уже кайфует на 5.3 и 4.0.
Обновить никак - портируй руками на новые версии фреймворка и совы.
Добро пожаловать в клуб "подумать сначала о стоимости поддержки проекта и минимизировать архитектурные издержки в следствии процессов поддержки"
сам фреймворк тоже обновить только руками?
после установки заметил, что у меня версия sleeping owl 2, а ларавель версии 5.0.35
подскажите, как обновить so ?
кстати ответ на первый вопрос темы был такой
нужно было поменять
App\Model\Photo::Photo
на
App\Model\Photo::class
А просто admin/ работает?
Попробуй admin/photos
просто admin/ работает
если пробую admin/photos получаю Class 'app\Model\Photo' not found
bootstrapDirectory по умолчанию это
app/admin/
То есть модель админки должна быть в app/Admin/Photo.php
я регистрирую модель Photo, Добавляю туда
<?php
Admin::model(app\Model\Photo::class)->title('Фото')->with('photo_src')
->columns(function ()
{
Column::string('photo_src', 'Src');
}) ->form(function()
{
FormItem::text('photo_src', 'photo_src');
});
когда пытаюсь обратиться к admin/photo
получаю
You need to provide valid action for this route.
Установил sleeping owl, в доках написано
Конфигурация моделей SleepingOwl Admin должны быть расположены в директории bootstrapDirectory
создал папку bootstrapDirectory в app/Admin
там создаю файл Photo.php
в нем пишу следующее
<?php
Admin::model(App\Model\Photo::Photo);
моя модель Photo находится в app/Model/Photo.php
там такой код
<?php namespace App\Model;
use SleepingOwl\Models\SleepingOwlModel;
use Illuminate\Database\Eloquent\Model;
class Photo extends SleepingOwlModel {
protected $table = 'photo';
protected $primaryKey = 'photo_id';
public $timestamps = false;
protected $fillable = [
'photo_symbol_id',
'photo_src',
'photo_nationality_id',
'photo_color_id',
'photo_type_id',
'photo_moderation_id'
];
public function newUserUpload($save_path){
$this->photo_src = $save_path;
$this->photo_moderation_id = 2;
$this->save();
}
}
при попытке запуска ловлю ошибку
Undefined class constant 'Photo'
respectpick пишет:но у меня нет такого файла
Извиняюсь, версию не увидел. Посмотри по аналогии. В 5.1-5.2, например, это Auth/AuthController.php (возможно и в 5.0 он же). Смотри какие трейты он использует и ищи в vendor эти трейты. Так ты найдешь метод, который отвечает за сам логин пользователя. В конце меняй редирект на что душе угодно (только не в трейте, а в app\Http\Controllers\Auth\AuthController.php или подобном).
Скорее всего тебе нужен тот же метод, о котором я писал выше, попробуй его сначала поиском в папке vendor найти.
в общем, нашел этот трейт, там есть метод
public function redirectPath()
{
if(property_exists($this, 'redirectPath'))
{
return $this->redirectPath();
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
если пытаюсь переопределить у себя его, ловлю ошибку
TokenMismatchException in VerifyCsrfToken.php
В методе явно видно, что он ищет в свойствах redirectPath или redirectTo, но при объявлении этих свойств вообще никакой реакции на происходящее, тупо редиректит на home и все
А если поиском по проекту пройтись, по $redirectTo = '/home' или даже лучше просто '/home'?
Кажется, если в каких-то контроллерах это явно не указано, он от какого-то родителя наследует.
С другой-то стороны, так уж плохо, что он в контроллерах позволяет этим свойством рулить? Можно редиректить в зависимости от ситуации. Или что-то не так?
в том-то и дело, что не позволяет рулить! уже час пытаюсь различные переменные задавать и в тупую переопределять методы - ничего, просто редиректит на home и все!
в контроле версий у меня нет папки vendor, но там есть трейт, который вроде как должен рулить этим, но все-равно никак не реагирует
В Laravel давно эта проблема, никак по-человечески сделать не могут.
Перезапиши (не знаю как по-русски грамотно) метод sendLoginResponse() в LoginController.php
но у меня нет такого файла
если в файле app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
заменить
if ($this->auth->check())
{
return new RedirectResponse(url('/home'));
}
return $next($request);
на
if ($this->auth->check())
{
return new RedirectResponse(url('/'));
}
return $next($request);
то сайт падает с ошибкой Сайт ***.ru выполнил переадресацию слишком много раз.
версия 5.0.35
пытаюсь заюзать авторизацию из коробки, но проблема в том, что меня постоянно редиректит на /home после авторизации.
в доках написано, что нужно в PasswordController добавить
protected $redirectTo = '/';
но не помогает.
Пытался добавить в app/Http/Controllers/Auth/AuthController.php, опять же не помогает
увидел файл в app/Http/Controllers/Middleware/RedirectIfAuthenticated.php, там строка
if ($this->auth->check())
{
return new RedirectResponse(url('/home'));
}
return $next($request);
пытался там менять, не помогает
увидел, что редирект происходит в файле app/Http/Controllers/Middleware/Authenticate.php
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request); // вот тут
}
но как задать адрес редиректа? и где?