Skip to content

Instantly share code, notes, and snippets.

@fomvasss
Last active June 22, 2022 15:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fomvasss/72f6bd73f6bd1bc944a25422a827a18e to your computer and use it in GitHub Desktop.
Save fomvasss/72f6bd73f6bd1bc944a25422a827a18e to your computer and use it in GitHub Desktop.
Laravel

LARAVEL

Queues, Workers, Jobs

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

Supervisor

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

MIX

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
    });

How to redirect your Laravel website from the /public folder to the main domain

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

CRON

* * * * * cd /home/vagrant/www/laravel/meblidecor.test && php artisan schedule:run >> /dev/null 2>&1

Policy


Шлюзы и Политики

'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 => ‘Рассылка завершена успешно’ и тд.. ];

EMAIL

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your@gmail.com
MAIL_PASSWORD=parol
MAIL_ENCRYPTION=tls

For spatie/laravel-medialibrary

setlocale(LC_ALL,'en_US.UTF-8');

If key is more long

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

Ограничение скорости запросов API в Laravel 5.2

https://laravel.ru/posts/379

Настройка посредника 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();
    });
});

Spatie Downloader

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;
    }
    ```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment