Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
через ORM бы проблем не имел )))
не катит.
именно используя полиморфы хочу знать как каунтить.
есть в инете решения, но они громозские.
неее, для этого надо вытащить посты, потом считать их. нагрузка.
php artisan help
на предмет миграций.
вам необходимо убить/отключить миграцию.
посоветуйте, как , используя любые связи (лучше примером) дёрнуть кол-во записей у ссылаемой записи.
пример
запись "мой блог", содержит 25 постов. нужно дёрнуть это количество. именно на orm
чёт у мну ролики за шарики едут...
а так, всё отлично, всё работает.
да мне в принципе всё равно, просто люблю, когда "всё по полочкам"
решай сам, конечно ))
в принципе регистрация нужна.
ведь рано или поздно захочешь извещать автора объявления по email, а откуда взять проверенный/подтверждённый пользователем email, кроме как из процедуры регистрации ?
но лучше не трогать по принципу бородатого анекдота - "работает и не трогай!" ;-)
в догонку.
я бы тоже самое по гихабу сделал.
у меня есть решение, как спокойно сделать бутстрап3 с гита билдящимся без ошибок. то же самое по jquery итп, с использованием node.js/grunt/gulp
врядли будет такая халява.
опубликованный проект, даже идеально написаный - опубликованные _все_ дыры в проекте
php composer.phar create-project laravel\/laravel --prefer-dist
так работает?
если нет, то попробуйте сделать следующее:
mkdir ~/bin
mv composer.phar ~/bin/composer
файл .profile
PATH="~/.composer/vendor/bin:~/bin:$PATH"
перевойдите в оболочку
затем выполните
composer global require "laravel/installer=~1.1"
или, если ругнётся
composer global require "laravel\/installer=~1.1"
выгрузка лары будет выглядеть как
laravel new myproject
возможно доп.слеши надо доп.экранировать. зависит от условий
php.ini если мне не изменяет память несёт чего-то о разрешении использовать короткий синтаксис, возможно отключено.
МОГУ БЫТЬ НЕ ПРАВ и видел в другом несвязном месте.
на примере тегов.
есть много разных сущностей, к которым надо привязать тег.
пример: пользователь, блог, пост, картинка, чего-то ещё.
делать много пивотов и читать их сложно и долго
видел ли кто-то более разумное решение, чем 100500 пивотов?
а то каша полная
в любом случае в описанной модели ты можешь перекрёстно получить всё что необходимо.
нужно сложнее?
вот: http://laravel.com/docs/5.0/eloquent#has-many-through
А я всё таки настаиваю.
Посмотри сюда, я там подробно описал многое ко многому
https://laravel.ru/forum/viewtopic.php?id=944
На самом деле это компилированные вьюшки, и работают они по принципу кеширования -- живут какое-то время, не перекомпилируясь.
Эти вьюшки запрашиваются первым проходом, не обращая внимание на ресурсные вьюшки-исходники.
Что можно назвать кешированием первого уровня. Компиляция как бы кушает процессорное время, а работа с компилированными вьюшками так же как бы быстрее.
Почему "как бы" ? - потому что в любом случае кеширование на уровне движка удовольствие сомнительное.
Следовательно, предполагаю, что тебя интересует Кеширование второго уровня, - готового html-кода.
Угадал?
Если ты хочешь действительно кешировать html - делай это на урове веб-сервера, и не забудь разделить статический контент (css/картинки.js) от динамически-генерируемого.
Тут в помощь связка nginx-proxy + apache2
Во вторых, этот пост был основан на документации - читай внимательно, и самое главное и самое важное старайся формулировать вопрос правильно, что зачастую сразу даёт ответ.
Во первых делать не на коленке.
Как?
1. Создать модель Книги (создаст миграцию)
php artisan make:model Book
1.1. Допустим модель Книги такова
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
// таблица
protected $table = 'books';
// заполняемые поля в админке (например)
protected $fillable = [
'title',
'description'
];
// коллекция, вернёт все жанры выбранной книги
public function genres()
{
return $this->belongsToMany('App\Genres');
}
}
2. Создать модель Жанров (создаст миграцию)
php artisan make:model Genre
2.1. Допустим, модель такова
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Genre extends Model
{
// таблица
protected $table = 'genres';
// заполняемые поля в админке (например)
protected $fillable = [
'title'
];
// коллекция, вернёт все книги выбранного жанра
public function books()
{
return $this->belongsToMany('App\Book');
}
}
3. Отредактировать миграции
3.1. Книга
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBooksTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('books', function(Blueprint $table)
{
$table->increments('id');
$table->string('title')->index();
$table->text('description')->nullable()->default(NULL);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('books');
}
}
3.2. Жанры
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateGenresTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('genres', function(Blueprint $table)
{
$table->increments('id');
$table->string('title')->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('genres');
}
}
4. Применить миграцию, чтобы таблицы в БД существовали
php artisan migrate
5. СОЗДАТЬ ПИВОТ (создаёт миграцию)
НЕ РЕДАКТИРУЙ, но смотри
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBookGenrePivotTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('book_genre', function(Blueprint $table)
{
$table->integer('book_id')->unsigned()->index();
$table->integer('genre_id')->unsigned()->index();
$table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
$table->foreign('genre_id')->references('id')->on('genres')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('book_genre');
}
}
6. Применить миграцию с пивотом
php artisan migrate
Вследствии чего где-либо (за пример возьмём контроллер) работаешь таким образом:
Скажем, что это тело метода index() контроллера HomeController
.....
public function index()
{
// все книги (без жанров)
$books = Book::all();
dd($books->toArray())
// все книги с жанрами
$return = [];
$books = new Book;
foreach( $books->with('genres')->get() as $book ) {
$return[$book->id] = $book->toArray();
}
dd($return, $books);
// книга с жанрами
$book = Book::with('genres')->find(1);
dd($book);
// жанр №1 со всеми книгами
$genre = Genre::with('books')->find(1);
dd($genre);
// все жанры со всеми книгами
$return = [];
$genres = new Genre;
foreach( $genres->with('books')->get() as $genre ) {
$return[$genre->id] = $genre->toArray();
}
}
.....
Дмитрий, Вы как-то тему обрубили... Так не честно, я только попкорн купил )))))
а сразу с модельками делать, не судьба?
с модельками можно нормальный запрос сделать не сильно напрягаясь.
такие подходы губят в корню хайлоад.
пойди путём НЕ усложнения.
1) обновляй несущие записи статикой. при добалении лайка пересчитывай конечное значение и инкрементируй/декрементируй его.
2) лайки в подобных связях актуальны НЕ ДЛЯ подсчётов, а для хранения указателей на тех же пользователей, чтобы показать кто лайкнул, не более.
старайся не делать поделку ради поделки
варианта 2:
1) статика - как и писал, писать в бд пути
2) динамика - собирать рекурсивным проходом (я за этот вариант)
а) на стороне сервера на рнр
б) на стороне яваскрипта на клиенте.
и Proger_XP, давай без нервов ))) поуважительней - люди разные с разным уровнем знаний в конкретных областях.
За участие - спасибо!
Мозговой штурм удался на славу
я уже всё реализовал
всё реализовыватся на уровне процедуры переключения + миддлваря.
по порядку:
Роутер
Route::get('/subauth', 'SubAuthController@getSubauth');
Route::get('/subauth/switch/{uid}', 'SubAuthController@getSwitch');
Route::get('/subauth/logout/{uid}', 'SubAuthController@getLogout');
Route::get('/subauth/list/{uid}', 'SubAuthController@getList');
Route::get('/subauth/unlist/{uid}', 'SubAuthController@getUnlist');
Route::post('/subauth/login', 'SubAuthController@postLogin');
Контроллер
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
use Input;
use Auth;
use App\User;
use Redirect;
use URL;
use Session;
use View;
class SubAuthController extends Controller
{
/**
* Конструктор
*
* @param \Illuminate\Contracts\Auth\Guard $auth
* @param \Illuminate\Http\Request $request
*/
public function __construct( Guard $auth, Request $request )
{
$this->auth = $auth;
$this->request = $request;
$this->middleware( 'auth' );
}
/**
* страница с суб-авторизацией, списком вторичных пользователей, управление ими
*/
public function getSubauth()
{
// показываем вьюшку
return View('subauth/index');
}
/**
* Пытаемся авторизовать вторичного пользователя
*/
public function postLogin()
{
// запоминаем основного/текущего пользователя, который встанет вниз списка вторичных пользователей.
$old_user = Auth::user();
// условия поиска пользователя
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
// логиним нового пользователя как основного <= и бага и фича. если хотите сидеть на одном, добавляя других - кода будет в 3-5 раз больше.
if ( $this->auth->attempt($credentials) )
{
// извлечение вторичных пользователей из сессии
$subLogins = Session::get('subLogins', []);
// вставка сохранённог, уже бывшего основного/текущего пользователя, в список вторичных пользователей
$subLogins[$old_user->id] = [
'is_listed' => (count($subLogins)>4) ? false: true,
'down_shifted' => time(),
'user' => $old_user,
];
// сохранение вторичных пользователей
Session::set('subLogins', $subLogins);
// уход
return Redirect::back();
}
else
{
// возврат старого пользователя с сообщением об ошибке
$this->auth->login($old_user);
return Redirect::back()
->withErrors( trans('login.user_not_found') );
}
}
/**
* переключает пользователя на вторичного, делая основным/текущим
*
* @param null $uid
*
* @return $this|\Illuminate\Http\RedirectResponse
*/
public function getSwitch($uid=null)
{
// запоминаем основного/текущего пользователя, который встанет вниз списка вторичных пользователей.
$old_user = Auth::user();
// извлечение вторичных пользователей из сессии
$subLogins = Session::get('subLogins', []);
// проверка на наличие запрашиваемого авторизованного пользователя
if ( !empty( $subLogins ) && isset( $subLogins[$uid] ) )
{ // НАШЛИ
// удаление включаемого пользователя из вторичного списка пользователей
unset( $subLogins[$uid] );
// Грузим пользователя
$User = User::find( $uid );
// проверка пользователя
if ( empty( $User ) )
{
// НЕ НАШЛИ
// выход с сообщением об ошибке
return Redirect::back()
->withErrors( trans('login.user_not_found') );
}
else
{
$this->auth->login( $User );
// вставка сохранённог, уже бывшего основного/текущего пользователя, в список вторичных пользователей
$subLogins[$old_user->id] = [
'is_listed' => (count($subLogins)>4) ? false: true, // фишка держать 5 приоритетных пользователей в некоеом списке быстрого доступа
'down_shifted' => time(), // дата отключения (внесения во вторичных пользователей)
'user' => $old_user,
];
// сохранение вторичных пользователей
Session::set('subLogins', $subLogins);
// уход
return Redirect::back();
}
}
else
{
// пустой массив вторичных пользователей, их нет
// выход с сообщением об ошибке
return Redirect::back()
->withErrors( trans('login.users_not_found') );
}
}
/**
* удаляет вторичного пользователя
*
* @param null $uid
*
* @return \Illuminate\Http\RedirectResponse
*/
public function getLogout($uid=null)
{
// извлечение вторичных пользователей из сессии
$subLogins = Session::get('subLogins', []);
// проверка на наличие запрашиваемого авторизованного пользователя
if ( !empty( $subLogins ) && isset( $subLogins[$uid] ) )
{ // НАШЛИ - удаляем
unset($subLogins[$uid]);
// сохранение вторичных пользователей
Session::set('subLogins', $subLogins);
}
// уход
return Redirect::back();
}
/**
* делает вторичного пользователя видимым в списке переключения (список быстрого доступа)
*
* @param null $uid
*
* @return \Illuminate\Http\RedirectResponse
*/
public function getList($uid=null)
{
// извлечение вторичных пользователей из сессии
$subLogins = Session::get('subLogins', []);
// проверка на наличие запрашиваемого авторизованного пользователя
if ( !empty( $subLogins ) && isset( $subLogins[$uid] ) )
{ // НАШЛИ - изменяем
$subLogins[$uid]['is_listed'] = true;
// сохранение вторичных пользователей
Session::set('subLogins', $subLogins);
}
// уход
return Redirect::back();
}
/**
* делает вторичного пользователя видимым только на странице управления
*
* @param null $uid
*
* @return \Illuminate\Http\RedirectResponse
*/
public function getUnlist($uid=null)
{
// извлечение вторичных пользователей из сессии
$subLogins = Session::get('subLogins', []);
// проверка на наличие запрашиваемого авторизованного пользователя
if ( !empty( $subLogins ) && isset( $subLogins[$uid] ) )
{ // НАШЛИ - изменяем
$subLogins[$uid]['is_listed'] = false;
// сохранение вторичных пользователей
Session::set('subLogins', $subLogins);
}
// уход
return Redirect::back();
}
}
Middleware
<?php namespace App\Http\Middleware;
use Closure;
use View;
use Session;
use Auth;
class UserSwitcher
{
/**
* сбрасываем вторичных пользователей (если есть) в сессию
*
* @param $request
* @param callable $next
*
* @return
*/
public function handle($request, Closure $next)
{
if ( Auth::check() )
{
$subLogins = Session::get('subLogins', []);
View::share( 'subLogins', $subLogins );
}
return $next($request);
}
}
View'шку сами придумывайте )))