Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
class View extends Laravel\View {
public static function file($bundle, $view, $directory) {
if($path = parent::file($bundle, $view, $directory)) {
return $path;
} elseif (file_exists($path = str_finish($directory, DS).$view.'.html')) {
return $path;
}
}
}
Что характерно, php выполняется внутри html, хотя на сервере такое прописывалось.
Добрый день, из любопытства решил попробовать расширить класс View, с целью рендерить файлы .html, и заблудился. Не могу проследить где происходит загрузка отображения.
Если вы знаете правильный путь, пожалуйста, подскажите.
Спасибо, попробую!
Спасибо за ответ! Но, насколько я понял, такой подход предполагает отдельный запрос для каждого элемента фильтра. Это подход быстрее чем один запрос, а затем манипуляция с массивами, я правильно понял? Если же, вы имели в виду, вообще один запрос сразу для всех элементов, я правда, не понимаю как можно выстроить такую конструкцию в Fluent.
Добрый день, прошу советов относительно реализации каталога товаров. Не получилось найти материалы в сети, которые бы мне помогли. Нужный мне функционал можно посмотреть тут: http://hotline()ua/computer/planshety/
Сразу приношу извинения, но кода не будет, только логика.
Функционал заведомо упрощен, без групп фильтров, категорий товаров, пагинации, и другого.
Есть список товаров (id, title, price, ...), список фильтров (id, title, suffix) и список элементов фильтров (id, filter_id, value) и связующая таблица (id, item_id, value_id).
Моя реализация работает так, при клике на элемент фильтра, который является ссылкой, генерируется запрос cо списком id всех задействованных элементов. Этот список парситься в массив, и с помощью where_in тянуться все задействованные элементы, первый запрос.
Жадно грузим все товары для этих элементов, второй запрос. После чего генерируем массив массивов из id этих товаров. Используем условие, что если элементы относятся к одному фильтру, id их товаров сливаются. На выходе массив вида: id фильтра => массив id товаров.
Получаем схождение этих массивов, и подставляем результат в where_in, получая все нужные товары, это третий запрос.
Теперь нужно сгенерировать фильтры. Грузим фильтры, жадно грузим их элементы. Четвертый и пятый запросы.
Выводим фильтра и их элементы, генерируя ссылки. Ссылки генерируються в зависимости присутствия id элемента в массиве получаемого из запроса. Если отсутствует, добавляем к этому запросу и подставляем в ссылку, если присутствует, убираем из запроса и подставляем в ссылку, присваивая ссылке класс.
Теперь о предварительном подсчете результатов. После каждого элемента в скобках присутствует число, которое показывает как измениться количество подходящих товаров после применения этого фильтра. Если из элементов этого фильтра нет ни одного активного, то просто число, которое показывает количество товаров (17). Но если уже хоть один элемент активен, это число со знаком плюс, которое показывает сколько товаров добавиться к текущему количеству (+8). Если такое число ноль, элемент не выводиться. Сложно объяснить, лучше посмотреть образец, который я привел выше.
Начиная с этого места, я очень сомневаюсь. Жадно загрузить count с динамическим запросом не получиться.
Можно делать отдельный count запрос для каждого элемента, подставляя в условие скорректированный массив id товаров, полученный выше. Это ~много~ запросов, что меня огорчает. Можно жадно загрузить все относящиеся к элементу товары. И потом уже сравнивать массив их id с вышеупомянутым массивом. Это один запрос, но быстрее ли он первого варианта. Так же, теоретически, можно отойти от отношений и вручную использовать join, но этот вариант я пока не обдумывал.
Собственно интересует каким путем пошли бы вы? Рад буду если вы поделитесь опытом. Заранее спасибо!
Я тоже не пользуюсь Блейдом, достаточно переименовать 'some_name.blade.php' в 'some_name.php'. А если вообще без рендеринга, обратите внимание на '$model->to_array()' и 'return Response::json($array)'.
Но если вам нужен лишь json, имеет смысл дождаться Laravel 4, выходит в конце мая, и имеет приятные методы для json ответов.
Вот еще, курс где достаточно Laravel связывают с Backbone, возможно увидете что-то полезное.
http://net.tutsplus.com/tutorials/javas … ew-course/
Понятно, спасибо! Работая над этим решением возник другой вопрос.
Есть два домена xyz.com и abc.xyz.com, по сути, это два разных сайта, все модели, классы, отображения, css, js разные, ничего общего. Логично разбить этот сайт на два приложения. Но есть один момент, сессии (стандартный класс Auth) должны быть общие. Выполнил вход на одном домене, авторизирован на другом.
Возможно ли реализовать общие сессии для двух приложений, в разных папках, с общей системной папкой? Должно быть Laravel шифрует сессии используя ключ, разный для каждого приложения, можно его задать вручную?
Тем временем, в настройках сессий (config/session.php), нашел такой параметр:
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| The domain for which the session cookie is available.
|
*/
'domain' => false,
На самом деле проще как раз таки контролировать единый канал вывода, а не множество каналов ввода. В шаблоне ты изначально сфокусирован на выводе, поэтому очень просто добавлять экраны в нужных местах. А вот помнить, где может быть потенциально опасный ввод на протяжении тысяч строк кода всего приложения — намного сложнее.
Да, вы правы, звучит логично. Думаю стоит пересмотреть свой подход. Спасибо!
Я пересмотрел свой класс, то что я в начале написал неверно. Так лучше:
class Input extends Laravel\Input {
public static function get($key = null, $default = null) {
$value = parent::get($key, $default);
return is_array($value) ? array_map(array('self', 'safe'), $value) : HTML::entities($value);
}
private static function safe($value) {
return HTML::entities($value);
}
}
Вы провели отличную работу, и уверен вам удобно работать. Но я думаю, я сам должен прийти к таким решениям, ориентируясь на свои потребности. Но все таки, относительно экранирования только во вью. Как мне спать по ночам, знаю что непосредственно в БД у меня могут находиться XSS в боевой готовности. И единственная причина их несрабатывания, это безопасный вью. Неужели экранировать перед помещением в БД, являеться излишним? Возможно разумнее перекрывать даже не Input, а Eloquent. В общем буду думать, искать.
Добрый день, по умолчанию в Laravel присутствует защита от SQL инькций, но воизбежание XSS приходиться переодически использовать HTML::entities(), удивительно что автоматическая защита не является опцией. Имели ли вы опыт расширения стандартного Input, и что из этого получилось? Признаюсь я на скорую руку поступил так:
class Input extends Laravel\Input {
public static function get($key = null, $default = null) {
$value = parent::get($key = null, $default = null);
return is_array($value) ? $value : HTML::entities($value);
}
public static function all() {
$input = parent::all();
foreach($input as $key => $value) {
$input[$key] = HTML::entities($value); //даже не array_map =)
}
return $input;
}
}
Теперь задумался о более ответственном подходе, и вот пришел советоваться.
После определенных телодвижений обнаружил ошибку такую ошибку:
Notice: Undefined property: Symfony\Component\HttpFoundation\LaravelResponse::$charset in /home/***/public_html/laravel/vendor/Symfony/Component/HttpFoundation/Response.php on line 221 Unhandled Exception Message: Undefined property: Laravel\Response::$content Location: /home/***/public_html/laravel/response.php on line 266 Stack Trace: #0 /home/***/public_html/laravel/laravel.php(42): Laravel\Error::native(8, 'Undefined prope...', '/home/***/p...', 266) #1 /home/***/public_html/laravel/response.php(266): Laravel\{closure}(8, 'Undefined prope...', '/home/***/p...', 266, Array) #2 /home/***/public_html/laravel/error.php(62): Laravel\Response->render() #3 /home/***/public_html/laravel/error.php(111): Laravel\Error::exception(Object(ErrorException), false) #4 /home/***/public_html/laravel/laravel.php(50): Laravel\Error::shutdown() #5 [internal function]: Laravel\{closure}() #6 {main}
Добрый день, возникла странная проблема.
echo Form::open('login', 'POST');
//username
//password
echo Form::close()
Route::post('login', function()
{
$data = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
Auth::attempt($data);
return Redirect::back();
});
До определенного, неизвестного, момента, все отлично работало. Но наступил этот момент, и начались проблемы. Из того что я понял, при вызове Auth::attempt($data); происходит переадресация, на тот же маршрут, но уже без $_POST. Независимо от правильности ввода. Как следствие попадание на 404.
, прочитал все понял, и написал глупость. Прошу прощения, был вечер. Единственное уточнение, что бы не заморачиваться с длинными именами свой класс назвал просто Query, в application.php/aliases это имя свободно, так что, думаю, проблем не будет. Правильно?
class Query extends Laravel\Database\Eloquent\Query {
function __clone() {
$this->table = clone $this->table;
}
}
$things = clone $items;
$things->table = clone $things->table;
Это порнография, сами понимаете. В любом случае у меня PHPclass Model extends Eloquent
, в ядро я стараюсь не лазить.
Но на для подстраховки уточню:
class Model extends Eloquent {
function __clone() {
$this->table = clone $this->table;
}
}
Это допустимая конструкция? Я ничего не перекрываю?
Спасибо большое за разъяснение архитектуры! Вы, должно быть, структуру наизусть знаете.
Добрый день, объясните пожалуйста данное поведение:
$items = Item::where('some', '=', 1);
$items->get();
$items = Item::where('some', '=', 1);
$items->take(10);
$items->get();
$items = Item::where('some', '=', 1);
$things = clone $items;
$things->take(10);
$items->get();
вернет 10 записей? Я ведь установил лимит $things, а не $items. Заранее спасибо!
при входе на одном домене выполняется автоматический вход на всех связанных
Отлично! Это, думаю, оптимальное решение для меня. В очередной раз помогли мне, спасибо вам!
Понятно, спасибо! Работая над этим решением возник другой вопрос.
Есть два домена xyz.com и abc.xyz.com, по сути, это два разных сайта, все модели, классы, отображения, css, js разные, ничего общего. Логично разбить этот сайт на два приложения. Но есть один момент, сессии (стандартный класс Auth) должны быть общие. Выполнил вход на одном домене, авторизирован на другом.
Возможно ли реализовать общие сессии для двух приложений, в разных папках, с общей системной папкой? Должно быть Laravel шифрует сессии используя ключ, разный для каждого приложения, можно его задать вручную?
А в чём вопрос с Composer? Это обычный PHP-скрипт, если есть возможность их выполнять, то и он запустится. Нужно только подключение к Интернету для загрузки начальных пакетов.
Мне кажется использовать Composer чтобы развернуть Laravel, а потом им не пользоваться (я знаю что это великолепная и многообещающая штука, но я отталкиваюсь от своих потребностей), неправильный путь. Как шутка про IE, который включен в Windows лишь для того, что бы пользователь мог загрузить себе браузер. Но это скорее прихоть.
Пожалуйста!
Здравствуй, при переходе с CI надо четко понять определенные моменты которые там неявные.
Модель, это представление вашей таблицы, например:
В БД есть таблица «football_clubs», с полями «id» (PK), «title» (VARCHAR 15), «city» (VARCHAR 15), «year» (INT 4).
Создается модель, где указываетесь статическая переменная с именем этой таблицы в БД:
class Club extends Eloquent
{
public static $table = 'football_clubs';
}
Теперь с этим классом можно работать, экземпляры этого класса, это записи в таблице. Название переменных аналогичны названиям полей в указанной таблице. Манипулируем в контроллере, используя методы класса Fluent, которые использует класс Eloquent, от котрого наследуется наша модель:
class Football_Controller extends Base_Controller
{
public function action_index()
{
//Писать будем тут
}
}
$club = new Club;
$club->title = "Динамо";
$club->city = "Киев";
$club->year = 1927;
$club->save(); //Создана запись в таблице.
$club = new Club(array('title' => 'Реал', 'city' => 'Мадрид', 'year' => 1902));
$club->save(); //Создана еще одна запись в таблице.
$club = new Club(array('title' => 'Юнайтед', 'city' => 'Манчестер', 'year' => 1878));
$club->save(); //И еще одна.
$clubs = Club::all(); //Вернет все клубы
$dynamo = Club::find(1); //Найдет по ключу (ID)
$real_and_atletico = Club::where('city', '=', 'Мадрид')->get(); //Вернет массив клубов из Мадрида
$real = Club::where('city', '=', 'Мадрид')->first(); //Только первый попавшийся клуб из Мадрида (LIMIT 1)
$old_clubs = Club::where('year', '<', '1900')->order_by('year', 'desc')->get(); //Вернет все клубы у которых год меньше 1900
return View::make('football.index', array('old_clubs' => $old_clubs, 'dynamo' => $dynamo));
Можно использовать CI способ подвязки данных ко вью:
$data['dynamo'] = Club::where('title', '=', 'Динамо')->where('city', '=', 'Киев')->first();
$data['old_clubs'] = Club::where('year', '<', '1900')->order_by('year', 'desc')->get();
return View::make('football.index', $data);
А дальше по аналогии с CI, выводим во вью:
foreach($old_clubs as $club) {
echo $club->title . ' ' . $club->city . ' (' . $club->year . ')';
}
Или если был указан лимит в одну запись:
echo $dynamo->title . ' ' . $dynamo->city . ' (' . $dynamo->year . ')';
Повторяющиеся куски кода можно вынести в модель:
class Club extends Eloquent
{
public static $table = 'clubs';
public function full_name() {
return $this->title . ' ' . $this->city . ' (' . $this->year . ')';
}
}
echo $dynamo->full_name(); //Выведет "Динамо Киев (1927)"