php artisan queue:table
php artisan queue:failed-table
php artisan migrate
php artisan make:job ProcessPodcast
namespace App\Jobs;
class ProcessPodcast
{
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
public function handle(AudioProcessor $processor)
{
// Process uploaded podcast...
}
public function failed(Exception $exception)
{
// Send user notification of failure, etc...
}
}
namespace App\Http\Controllers;
class PodcastController extends Controller{
public function store(Request $request)
{
ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(10));
ProcessPodcast::withChain([new OptimizePodcast, new ReleasePodcast])->dispatch();
ProcessPodcast::dispatch($podcast)->onQueue('processing');
//(Your job class)::dispatch(параметри);
//$this->dispatch(new SendReminderEmail($user));
//dispatch(new App\Jobs\PerformTask);
//dispatch((new Job)->onQueue('high'));
}
}
Restarting in prod server
php artisan down
git pull origin dev
php artisan queue:restart
php artisan up
php artisan queue:work --tries=3
php artisan queue:work --timeout=30
namespace App\Jobs;
class ProcessPodcast implements ShouldQueue{
public $tries = 5;
public $timeout = 120;
//....
}
php artisan queue:work
php artisan queue:work --once
php artisan queue:work redis --queue=emails
php artisan queue:work --queue=high,low
php artisan queue:failed
php artisan queue:retry 5
php artisan queue:retry all
php artisan queue:restart
php artisan queue:work --timeout=60
php artisan queue:work --sleep=3
sudo apt-get install supervisor
whoami
Cd in /etc/supervisor/conf.d directory. For example, let's create a laravel-worker.conf file that starts and monitors a queue:work process:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log
sudo service supervisor reload
sudo /etc/init.d/supervisor restart
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
https://laravel.com/docs/5.5/queues https://laravel.com/docs/5.5/queues#supervisor-configuration
Full API
mix.js(src, output);
mix.react(src, output); //<-- Identical to mix.js(), but registers React Babel compilation.
mix.extract(vendorLibs);
mix.sass(src, output);
mix.standaloneSass('src', output); //<-- Faster, but isolated from Webpack.
mix.fastSass('src', output); //<-- Alias for mix.standaloneSass().
mix.less(src, output);
mix.stylus(src, output);
mix.postCss(src, output, [require('postcss-some-plugin')()]);
mix.browserSync('my-site.dev');
mix.combine(files, destination);
mix.babel(files, destination); //<-- Identical to mix.combine(), but also includes Babel compilation.
mix.copy(from, to);
mix.copyDirectory(fromDir, toDir);
mix.minify(file);
mix.sourceMaps(); Enable sourcemaps
mix.version(); Enable versioning.
mix.disableNotifications();
mix.setPublicPath('path/to/public');
mix.setResourceRoot('prefix/for/resource/locators');
mix.autoload({}); //<-- Will be passed to Webpack's ProvidePlugin.
mix.webpackConfig({}); //<-- Override webpack.config.js, without editing the file directly.
mix.then(function () {}) //<-- Will be triggered each time Webpack finishes building.
mix.options({
extractVueStyles: false, //Extract .vue component styling to file, rather than inline.
processCssUrls: true, //Process/optimize relative stylesheet url()'s. Set to false, if you don't want them touched.
purifyCss: false, //Remove unused CSS selectors.
uglify: {}, //Uglify-specific options. https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
postCss: [] //Post-CSS options: https://github.com/postcss/postcss/blob/master/docs/plugins.md
});
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
* * * * * cd /home/vagrant/www/laravel/meblidecor.test && php artisan schedule:run >> /dev/null 2>&1
Шлюзы и Политики
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
в App\Providers\AuthServiceProvider:
/**
* Регистрация всех сервисов аутентификации / авторизации.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Gate::define('update-post', function ($user, $post) {
return $user->id == $post->user_id;
});
}
Проверка в контроллере:
if (Gate::allows('update-post', $post)) {
// Текущий пользователь может редактировать статью...
}
if (Gate::denies('update-post', $post)) {
// Текущий пользователь не может редактировать статью...
}
Для определения, авторизован ли конкретный пользователь на выполнение действия, используйте метод forUser() фасада Gate:
if (Gate::forUser($user)->allows('update-post', $post)) {
// Пользователь может редактировать статью...
}
if (Gate::forUser($user)->denies('update-post', $post)) {
// Пользователь не может редактировать статью...
}
Создание политик
php artisan make:policy PostPolicy --model=Post
Регистрация политик
class AuthServiceProvider extends ServiceProvider
{
/**
* Привязка политик для приложения.
*
* @var array
*/
protected $policies = [
Post::class => PostPolicy::class,
];
}
Создание метода политики:
class PostPolicy
{
/**
* Определение, может ли данная статья редактироваться пользователем.
*
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
public function create(User $user)
{
return isModerator() && auth()->user()->canAddContent();
}
}
Фильтры политик Если вы хотите запретить всю авторизацию для пользователя, вам надо вернуть false из метода before(). Если вернётся null, авторизация перейдёт к методу политики.
public function before($user, $ability)
{
if ($user->role == 'admin') {
return true;
}
}
Авторизация действий с помощью политик
if ($user->can('update', $post)) {
//
}
Имя класса будет использовано для определения того, какая политика авторизует действие:
if ($user->can('create', App\Models\Post::class)) {
// Выполняется метод "create" соответствующей политики...
}
Авторизация действий Через посредника
use App\Post;
Route::put('/post/{post}', function (Post $post) {
// Текущий пользователь может редактировать статью...
})->middleware('can:update,post');
Через вспомогательные методы контроллера
$this->authorize('update', $post);
$this->authorize($post); //Автоматическое определение методов политики
$this->authorizeForUser($user, 'update', $post);
Через шаблоны Blade
@can
@elsecan
@endcan
@cannot
@endcannot
Проверка прав С помощью фасада Gate
if (Gate::denies('update-post', $post)) {
abort(403);
}
Метод allows() обратен методу denies() и возвращает true, если действие авторизовано. Метод check() — псевдоним метода allows().
if (Gate::forUser($user)->allows('update-post', $post)) {
//
}
Gate::define('delete-comment', function ($user, $post, $comment) {
//
});
С помощью модели User
if ($request->user()->cannot('update-post', $post)) {
abort(403);
}
В запросах форм
public function authorize()
{
$postId = $this->route('post');
return Gate::allows('update', Post::findOrFail($postId));
}
это надо поместить не в конфиг а в саму модель для которой эти статусы используются
обычно делают так, заводят константы для каждого статуса
const MAILING_STATUS_FRESH = 0; const MAILING_STATUS_SUCCESS = 1;
и тд..
Для того чтобы когда я в коде встретил: $campaign->mailing_status = Campaign::MAILING_STATUS_SUCCESS;
было понятно сразу что за статус присваивается
В случае если нужно получить label в кириллице или еще что-то можно завести в модели
public $mailing_statuses = [ self::MAILING_STATUS_FRESH => ‘Рассылка не запускалась’, self::MAILING_STATUS_SUCCESS => ‘Рассылка завершена успешно’ и тд.. ];
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
[email protected]
MAIL_PASSWORD=parol
MAIL_ENCRYPTION=tls
setlocale(LC_ALL,'en_US.UTF-8');
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
Настройка посредника throttle Давайте немного настроим. Сделаем ограничение на 5 попыток в минуту.
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5'], function () {
Route::get('people', function () {
return Person::all();
});
});
А теперь сделаем так, что если кто-то достигнет предела, то ему надо будет ждать 10 минут.
PHP
Route::group(['prefix' => 'api', 'middleware' => 'throttle:5,10'], function () {
Route::get('people', function () {
return Person::all();
});
});
public function getTempFile($url): string
{
$temporaryFile = tempnam(sys_get_temp_dir(), 'media-library');
$fh = fopen($temporaryFile, 'w');
$curl = curl_init($url);
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FAILONERROR => true,
CURLOPT_FILE => $fh,
CURLOPT_TIMEOUT => 35,
CURLOPT_FOLLOWLOCATION => true,
];
$headers = [
//'Content-Type: image/*',
'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:28.0) Gecko/20100101 Firefox/28.0',
];
curl_setopt_array($curl, $options);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if (false === curl_exec($curl)) {
curl_close($curl);
fclose($fh);
throw UnreachableUrl::create($url);
}
curl_close($curl);
fclose($fh);
return $temporaryFile;
}
```