Laravel: How to Show Number/List of Users Currently Online

If you want to show the number or list of users currently online on your website, there are a few ways to do it. In this tutorial, we will show you two of them.

Notice: To be fair, the most accurate would be to use web sockets and transfer that «live» information with tools like Soketi, but it requires way more configuration. In this tutorial, we went for simple options.

So, our actual goal is to save the last activity of the user. We can achieve it with a built-in Laravel session driver or manually with Middleware.

Option 1: Change the Session Driver to «Database»

Create a sessions table and migrate the database.

php artisan session:table
php artisan migrate

Update the SESSION_DRIVER value in the environment file to database.

.env or in config session.php instead of evp

SESSION_DRIVER=database

Now you can retrieve the total online visitor count:

use Illuminate\Support\Facades\DB;

function getOnlineUserCount()
{
return DB::table(config('session.table'))->count();
}

Retrieve logged-in users:

use App\Models\User;
use Illuminate\Support\Facades\DB;
 
function getLoggedInUsers()
{
    return DB::table(config('session.table'))
        ->distinct()
        ->select(['users.id', 'users.name', 'users.email'])
        ->whereNotNull('user_id')
        ->leftJoin('users', config('session.table') . '.user_id', '=', 'users.id')
        ->get();
}

Get active users in the last five minutes:

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
 
function getActiveUsersInLastMinutes(int $minutes)
{
    return DB::table(config('session.table'))
        ->distinct()
        ->select(['users.id', 'users.name', 'users.email'])
        ->whereNotNull('user_id')
        ->where('sessions.last_activity', '>', Carbon::now()->subMinutes($minutes)->getTimestamp())
        ->leftJoin('users', config('session.table') . '.user_id', '=', 'users.id')
        ->get();
}

Option 2: Middleware to Save Last Activity

Add the last_activity column to the users table.

php artisan make:migration add_last_activity_column_to_users_table
Schema::table('users', function (Blueprint $table) {
    $table->integer('last_activity')->index();
});

Do not forget to add the last_activity value everywhere you create the user.

User::create([
    // ...
    'last_activity' => now()->getTimestamp(),
]);

And add it into the fillable array on the User Model:

app/Models/User.php

protected $fillable = [
    // ...
    'last_activity',
];

Create the UpdateLastActivity Middleware.

php artisan make:middleware UpdateLastActivity

app/Http/Middleware/UpdateLastActivity.php

namespace App\Http\Middleware;
 
use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
 
class UpdateLastActivity
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if ($user = auth()->user()) {
            $user->timestamps    = false;
            $user->last_activity = now()->getTimestamp();
            $user->saveQuietly();
        }
 
        return $next($request);
    }
}

We set $user->timestamps = false only for this call to keep the updated_at field untouched. Otherwise, updated_at and last_activity will refer to the same time, and technically we are not updating the user.

The user model is saved by calling the saveQuietly method not to fire any observers registered with the user model with every request. This would be an unwanted side effect.

Finally, register UpdateLastActivity Middleware.

app/Http/Kernel.php

protected $middlewareGroups = [
    'web' => [
        // ...
        \App\Http\Middleware\UpdateLastActivity::class, 
    ],

Now you can query Users by their activity using Eloquent, disregarding what session driver you use.

User::where(
    'last_activity',
    '>',
    now()->subMinutes(5)->getTimestamp()
)
->get();

Проект на Laravel 10 + Bootstrap 5 + Jquery

Ставим фреймворк

composer create-project laravel/laravel

Ставим пакет для интерфейса

composer require laravel/ui

Устанавливаем bootstrap 5

php artisan ui bootstrap --auth

Выполняем

npm install 

Ставим bootstrap-icons

npm install bootstrap-icons 

Inside your project, open the file resources\sass\app.scss and add :

@import 'bootstrap-icons/font/bootstrap-icons.css';
// Fonts
@import url('https://fonts.bunny.net/css?family=Nunito');

// Variables
@import 'variables';

// Bootstrap
@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons.css';

Import vite.config.js Bootstrap 5 Path

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import path from 'path'
export default defineConfig({
plugins: [
laravel({
input: [
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
],
resolve: {
alias: {
'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
}
},
});

Update bootstrap.js

npm install lodash
import loadash from 'lodash';
window._ = loadash;

// UPDATE THIS LINES OF bootstrap.js FILE
import $ from 'jquery';
window.$ = $;

import * as Popper from '@popperjs/core'
window.Popper = Popper

import 'bootstrap';

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

import axios from 'axios';
window.axios = axios;

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo';

// import Pusher from 'pusher-js';
// window.Pusher = Pusher;

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: import.meta.env.VITE_PUSHER_APP_KEY,
//     wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
//     wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
//     wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
//     forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
//     enabledTransports: ['ws', 'wss'],
// });

Now we need to import bootstrap 5 SCSS path in resources/js/app.js file:

import './bootstrap';
import '../sass/app.scss'

use @vite directive

@vite(['resources/js/app.js'])

views/layouts/app.blade

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Install Bootstrap 5 in Laravel 10 With Vite') }}</title>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    @vite(['resources/js/app.js'])

</head>
<body>
    <div id="app">
        <nav >
            <div >
                <a  href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button  type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span ></span>
                </button>

                <div  id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul >

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul >
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li >
                                    <a  href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li >
                                    <a  href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li >
                                <a id="navbarDropdown"  href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div  aria-labelledby="navbarDropdown">
                                    <a  href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" >
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main >
            @yield('content')
        </main>
    </div>
</body>
</html>

Installing jQuery in Laravel with Vite

jQuery is installed using a node package manager, with a single command from the terminal. I will use npm.

At the root folder of your Laravel application run the following command.

npm install jquery --save-dev

You need to npm run build command to create asset bootstrap 5.

npm run build

 

Importing Select2 & Laravel Vite

To get it working without alias, follow these steps:

  1. Install jquery and select2:
npm i jquery select2 --save-dev
  1. Edit bootstrap.js for referencing jquery and select2
// import jquery and select2
import $ from "jquery";
import select2 from 'select2';
window.$ = $; // <-- jquery must be set
select2(); // <-- select2 must be called
  1. Import select2 CSS in app.js
//-- Select2
import "/node_modules/select2/dist/css/select2.css";
//--
import '../css/app.css';
// ...

Now you can use it in your components:

$('.js-example-basic-single').select2();

Сброс cached views в Laravel через middleware

Создаем middleware ClearViewCache

<?php

namespace App\Http\Middleware;

use Artisan;
use Closure;

class ClearViewCache
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (env('APP_DEBUG') || env('APP_ENV') === 'local')
Artisan::call('view:clear');

return $next($request);
}
}

регистрируем его в app/Http/Kernel.php в блоке protected $middleware

\App\Http\Middleware\ClearViewCache::class,

Изменяем в config/app.php

'env' => env('APP_ENV', 'local'), // production
'debug' => env('APP_DEBUG', true),

Сборка проекта на Laravel 6

скачиваем и устанавливаем node.js если его в системе нет https://nodejs.org/en/

устанавливаем Laravel using Composer

composer global require laravel/installer
laravel new project_name
composer require laravel/ui
php artisan ui bootstrap
npm install && npm run dev

Установка последней версии Bootstrap через NPM

npm install bootstrap --save-dev
composer require maatwebsite/excel

composer require phpoffice/phpword

composer require mpdf/mpdf

composer require dompdf/dompdf

composer require tecnickcom/tcpdf

composer require jpgraph/jpgraph

composer require setasign/fpdf

composer require doctrine/dbal

composer require laravelcollective/html

composer require components/jquery

composer require components/jqueryui

composer require select2/select2

composer require fortawesome/font-awesome

composer require techlab/smartwizard

Настраиваем jquery jqueryui select2 awesome

Create Service Provider in ‘app/Providers/AssetServiceProvider.php

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AssetServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot()
{
// jquery
$this->publishes([
base_path('vendor/components/jquery/jquery.js') => public_path('vendor/jquery/js/jquery.js'),
], 'jquery');
// jqueryui
$this->publishes([
base_path('vendor/components/jqueryui/jquery-ui.js') => public_path('vendor/jqueryui/js/jquery-ui.js'),
base_path('vendor/components/jqueryui/themes/base/jquery-ui.css') => public_path('vendor/jqueryui/css/jquery-ui.css'),
], 'jquery-ui');
// select2
$this->publishes(
[
base_path('vendor/select2/select2/dist/css/select2.min.css') => public_path('vendor/select2/css/select2.min.css'),
base_path('vendor/select2/select2/dist/js/select2.min.js') => public_path('vendor/select2/js/select2.min.js'),
],
'select2'
);
//FONT AWESOME
$this->publishes(
[
//css
base_path('vendor/fortawesome/font-awesome/css/all.min.css') => public_path('vendor/fortawesome/css/all.min.css'),
base_path('vendor/fortawesome/font-awesome/css/brands.min.css') => public_path('vendor/fortawesome/css/brands.min.css'),
base_path('vendor/fortawesome/font-awesome/css/fontawesome.min.css') => public_path('vendor/fortawesome/css/fontawesome.min.css'),
base_path('vendor/fortawesome/font-awesome/css/regular.min.css') => public_path('vendor/fortawesome/css/regular.min.css'),
base_path('vendor/fortawesome/font-awesome/css/solid.min.css') => public_path('vendor/fortawesome/css/solid.min.css'),
base_path('vendor/fortawesome/font-awesome/css/svg-with-js.min.css') => public_path('vendor/fortawesome/css/svg-with-js.min.css'),
base_path('vendor/fortawesome/font-awesome/css/v4-shims.min.css') => public_path('vendor/fortawesome/css/v4-shims.min.css'),
//js
base_path('vendor/fortawesome/font-awesome/js/all.min.js') => public_path('vendor/fortawesome/js/all.min.js'),
base_path('vendor/fortawesome/font-awesome/js/brands.min.js') => public_path('vendor/fortawesome/js/brands.min.js'),
base_path('vendor/fortawesome/font-awesome/js/conflict-detection.min.js') => public_path('vendor/fortawesome/js/conflict-detection.min.js'),
base_path('vendor/fortawesome/font-awesome/js/fontawesome.min.js') => public_path('vendor/fortawesome/js/fontawesome.min.js'),
base_path('vendor/fortawesome/font-awesome/js/regular.min.js') => public_path('vendor/fortawesome/js/regular.min.js'),
base_path('vendor/fortawesome/font-awesome/js/solid.min.js') => public_path('vendor/fortawesome/js/solid.min.js'),
base_path('vendor/fortawesome/font-awesome/js/v4-shims.min.js') => public_path('vendor/fortawesome/js/v4-shims.min.js'),
// web fonts
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.eot') => public_path('vendor/fortawesome/webfonts/fa-brands-400.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.svg') => public_path('vendor/fortawesome/webfonts/fa-brands-400.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.ttf') => public_path('vendor/fortawesome/webfonts/fa-brands-400.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.woff') => public_path('vendor/fortawesome/webfonts/fa-brands-400.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.woff2') => public_path('vendor/fortawesome/webfonts/fa-brands-400.woff2'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.eot') => public_path('vendor/fortawesome/webfonts/fa-regular-400.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.svg') => public_path('vendor/fortawesome/webfonts/fa-regular-400.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.ttf') => public_path('vendor/fortawesome/webfonts/fa-regular-400.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.woff') => public_path('vendor/fortawesome/webfonts/fa-regular-400.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.woff2') => public_path('vendor/fortawesome/webfonts/fa-regular-400.woff2'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.eot') => public_path('vendor/fortawesome/webfonts/fa-solid-900.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.svg') => public_path('vendor/fortawesome/webfonts/fa-solid-900.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.ttf') => public_path('vendor/fortawesome/webfonts/fa-solid-900.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.woff') => public_path('vendor/fortawesome/webfonts/fa-solid-900.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.woff2') => public_path('vendor/fortawesome/webfonts/fa-solid-900.woff2'),

],
'awesome'
);
}

/**
* Register any application services.
*/
public function register()
{
//
}
}

Register Service Provider in ‘config/app.php‘:

'providers' => [
    ...
    App\Providers\AssetServiceProvider::class,
    ...
]

Edit in  ‘composer.json‘:

"scripts": {

...

"post-update-cmd": [
"php artisan config:clear",
"php artisan cache:clear",

"php artisan vendor:publish --tag=jquery --force",
"php artisan vendor:publish --tag=jquery-ui --force",
"php artisan vendor:publish --tag=select2 --force",
"php artisan vendor:publish --tag=awesome --force"
]
}

Run composer update

Добавляем в template

{{--jquery--}}
<script src="{{asset('vendor/jquery/js/jquery.js')}}"></script>

<!-- Fonts fontawesome -->
<link media="all" type="text/css" rel="stylesheet" href="{{asset('vendor/fortawesome/css/all.min.css')}}">
<script src="{{asset('vendor/fortawesome/js/all.min.js')}}"></script>

{{--jquery-ui--}}
<script src="{{asset('vendor/jqueryui/js/jquery-ui.js')}}"></script>

{{--select2--}}
<link rel="stylesheet" href="{{ asset('vendor/select2/css/select2.min.css') }}">
<script src="{{ asset('vendor/select2/js/select2.min.js') }}"></script>

Ставим центавр и настраиваем его согласно инструкции

composer require srlabs/centaur
composer require vinkla/hashids

Installation

Install the Package Via Composer:

$ composer require srlabs/centaur

Add the Service Provider to your config/app.php file:

'providers' => array(
    ...
    Centaur\CentaurServiceProvider::class,
    ...
)

This package will not make use of automatic package discovery — you will need to register it manually. This is intentional.

Usage in New Applications

If you are starting a new Laravel 5.* application, this package provides a convenient way to get up and running with Cartalyst\Sentinel very quickly. Start by removing the default auth scaffolding that ships with a new Laravel 5.1 application:

$ php artisan centaur:spruce

Next, use Centaur’s scaffolding command to create basic Auth Controllers and Views in your application:

$ php artisan centaur:scaffold

Publish the Cartalyst\Sentinel assets:

$ php artisan vendor:publish --provider="Cartalyst\Sentinel\Laravel\SentinelServiceProvider"

Run your database migrations:

$ php artisan migrate

Run the Database Seeder. You may need to re-generate the autoloader before this will work:

$ composer dump-autoload
$ php artisan db:seed --class="SentinelDatabaseSeeder"

You will also need to add these routes to your routes.php file:

// Authorization
Route::get('login', 'Auth\SessionController@getLogin')->name('auth.login.form');
Route::post('login', 'Auth\SessionController@postLogin')->name('auth.login.attempt');
Route::any('logout', 'Auth\SessionController@getLogout')->name('auth.logout');

// Registration
Route::get('register', 'Auth\RegistrationController@getRegister')->name('auth.register.form');
Route::post('register', 'Auth\RegistrationController@postRegister')->name('auth.register.attempt');

// Activation
Route::get('activate/{code}', 'Auth\RegistrationController@getActivate')->name('auth.activation.attempt');
Route::get('resend', 'Auth\RegistrationController@getResend')->name('auth.activation.request');
Route::post('resend', 'Auth\RegistrationController@postResend')->name('auth.activation.resend');

// Password Reset
Route::get('password/reset/{code}', 'Auth\PasswordController@getReset')->name('auth.password.reset.form');
Route::post('password/reset/{code}', 'Auth\PasswordController@postReset')->name('auth.password.reset.attempt');
Route::get('password/reset', 'Auth\PasswordController@getRequest')->name('auth.password.request.form');
Route::post('password/reset', 'Auth\PasswordController@postRequest')->name('auth.password.request.attempt');

// Users
Route::resource('users', 'UserController');

// Roles
Route::resource('roles', 'RoleController');

// Dashboard
Route::get('dashboard', function () {
    return view('Centaur::dashboard');
})->name('dashboard');

This is only meant to be a starting point; you can change them as you see fit. Make sure you read through your new Auth Controllers and understand how they work before you make any changes.

Centaur automatically installs Sentinel and registers the SentinelActivations, and Reminders aliases for you. Detailed instructions for using Sentinel can be found here.

If you do decide to make use of Laravel’s Route::resource() option, you will need to use Form Method Spoofing to access some of those generated routes.

Установка и подключение bootstrap jquery select2 fontawesome в проекте Laravel

composer require twbs/bootstrap

composer require components/jquery

composer require components/jqueryui

composer require select2/select2

composer require fortawesome/font-awesome

Create Service Provider in ‘app/Providers/AssetServiceProvider.php

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AssetServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot()
{
// bootstrap
$this->publishes([
base_path('vendor/twbs/bootstrap/dist/css/bootstrap.min.css') => public_path('vendor/bootstrap/css/bootstrap.min.css'),
base_path('vendor/twbs/bootstrap/dist/css/bootstrap-grid.min.css') => public_path('vendor/bootstrap/css/bootstrap-grid.min.css'),
base_path('vendor/twbs/bootstrap/dist/css/bootstrap-reboot.min.css') => public_path('vendor/bootstrap/css/bootstrap-reboot.min.css'),

base_path('vendor/twbs/bootstrap/dist/js/bootstrap.min.js') => public_path('vendor/bootstrap/js/bootstrap.min.js'),
base_path('vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js') => public_path('vendor/bootstrap/js/bootstrap.bundle.min.js'),
], 'bootstrap');
// jquery
$this->publishes([
base_path('vendor/components/jquery/jquery.js') => public_path('vendor/jquery/js/jquery.js'),
], 'jquery');
// jqueryui
$this->publishes([
base_path('vendor/components/jqueryui/jquery-ui.js') => public_path('vendor/jqueryui/js/jquery-ui.js'),
], 'jquery-ui');
// select2
$this->publishes(
[
base_path('vendor/select2/select2/dist/css/select2.min.css') => public_path('vendor/select2/css/select2.min.css'),
base_path('vendor/select2/select2/dist/js/select2.min.js') => public_path('vendor/select2/js/select2.min.js'),
],
'select2'
);
//FONT AWESOME
$this->publishes(
[
//css
base_path('vendor/fortawesome/font-awesome/css/all.min.css') => public_path('vendor/fortawesome/css/all.min.css'),
base_path('vendor/fortawesome/font-awesome/css/brands.min.css') => public_path('vendor/fortawesome/css/brands.min.css'),
base_path('vendor/fortawesome/font-awesome/css/fontawesome.min.css') => public_path('vendor/fortawesome/css/fontawesome.min.css'),
base_path('vendor/fortawesome/font-awesome/css/regular.min.css') => public_path('vendor/fortawesome/css/regular.min.css'),
base_path('vendor/fortawesome/font-awesome/css/solid.min.css') => public_path('vendor/fortawesome/css/solid.min.css'),
base_path('vendor/fortawesome/font-awesome/css/svg-with-js.min.css') => public_path('vendor/fortawesome/css/svg-with-js.min.css'),
base_path('vendor/fortawesome/font-awesome/css/v4-shims.min.css') => public_path('vendor/fortawesome/css/v4-shims.min.css'),
//js
base_path('vendor/fortawesome/font-awesome/js/all.min.js') => public_path('vendor/fortawesome/js/all.min.js'),
base_path('vendor/fortawesome/font-awesome/js/brands.min.js') => public_path('vendor/fortawesome/js/brands.min.js'),
base_path('vendor/fortawesome/font-awesome/js/conflict-detection.min.js') => public_path('vendor/fortawesome/js/conflict-detection.min.js'),
base_path('vendor/fortawesome/font-awesome/js/fontawesome.min.js') => public_path('vendor/fortawesome/js/fontawesome.min.js'),
base_path('vendor/fortawesome/font-awesome/js/regular.min.js') => public_path('vendor/fortawesome/js/regular.min.js'),
base_path('vendor/fortawesome/font-awesome/js/solid.min.js') => public_path('vendor/fortawesome/js/solid.min.js'),
base_path('vendor/fortawesome/font-awesome/js/v4-shims.min.js') => public_path('vendor/fortawesome/js/v4-shims.min.js'),
// web fonts
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.eot') => public_path('vendor/fortawesome/webfonts/fa-brands-400.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.svg') => public_path('vendor/fortawesome/webfonts/fa-brands-400.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.ttf') => public_path('vendor/fortawesome/webfonts/fa-brands-400.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.woff') => public_path('vendor/fortawesome/webfonts/fa-brands-400.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-brands-400.woff2') => public_path('vendor/fortawesome/webfonts/fa-brands-400.woff2'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.eot') => public_path('vendor/fortawesome/webfonts/fa-regular-400.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.svg') => public_path('vendor/fortawesome/webfonts/fa-regular-400.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.ttf') => public_path('vendor/fortawesome/webfonts/fa-regular-400.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.woff') => public_path('vendor/fortawesome/webfonts/fa-regular-400.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-regular-400.woff2') => public_path('vendor/fortawesome/webfonts/fa-regular-400.woff2'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.eot') => public_path('vendor/fortawesome/webfonts/fa-solid-900.eot'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.svg') => public_path('vendor/fortawesome/webfonts/fa-solid-900.svg'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.ttf') => public_path('vendor/fortawesome/webfonts/fa-solid-900.ttf'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.woff') => public_path('vendor/fortawesome/webfonts/fa-solid-900.woff'),
base_path('vendor/fortawesome/font-awesome/webfonts/fa-solid-900.woff2') => public_path('vendor/fortawesome/webfonts/fa-solid -900.woff2'),

],
'awesome'
);
}

/**
* Register any application services.
*/
public function register()
{
//
}
}

Register Service Provider in ‘config/app.php‘:

'providers' => [
    ...
    App\Providers\AssetServiceProvider::class,
    ...
]

Edit in  ‘composer.json‘:

"scripts": {

...

"post-update-cmd": [
"php artisan config:clear",
"php artisan cache:clear",

"php artisan vendor:publish --tag=bootstrap --force",
"php artisan vendor:publish --tag=jquery --force",
"php artisan vendor:publish --tag=jquery-ui --force",
"php artisan vendor:publish --tag=select2 --force",
"php artisan vendor:publish --tag=awesome --force"
]
}

Run composer update

Template:

<!doctype html>

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Laravel</title>

<!-- Styles -->
{{ Html::style('css/style.css') }}

{{--bootstrap css--}}
<link media="all" type="text/css" rel="stylesheet" href="{{asset('vendor/bootstrap/css/bootstrap.min.css')}}">

{{--jquery--}}
<script src="{{asset('vendor/jquery/js/jquery.js')}}"></script>

{{--bootstrap js--}}
<script src="{{asset('vendor/bootstrap/js/bootstrap.min.js')}}"></script>

<!-- Fonts fontawesome -->
<link media="all" type="text/css" rel="stylesheet" href="{{asset('vendor/fortawesome/css/all.min.css')}}">
<script src="{{asset('vendor/fortawesome/js/all.min.js')}}"></script>

{{--jquery-ui--}}
<script src="{{asset('vendor/jqueryui/js/jquery-ui.js')}}"></script>

{{--select2--}}
<link rel="stylesheet" href="{{ asset('vendor/select2/css/select2.min.css') }}">
<script src="{{ asset('vendor/select2/js/select2.min.js') }}"></script>
</head>
<body>

<div class="col-12 col-md-9 pt-5">
@yield('content')
</div>
</body>
</html>

Инструкция для Oregon Scientific BAR208HG

oregon_scientific_bar208hg

Самые частые проблемы и способы их решения.

Основные «неисправности» устройств Oregon Scientific, которые на самом деле исправны;

1. Подавляющее число устройств, имеют заявленную «неисправность», связанную с «неработоспособностью» внешнего датчика (нет информации, не определяется датчик, неустойчивая связь)

Это в первую очередь из-за разряженных батарей (комплектные батарейки могут быть уже подсевшими), или разные каналы на датчике и станции, или неправильно проведена процедура подключения датчика (поиск датчика идет 2 минуты после нажатия RESET на основном блоке, этот RESET должен быть последним).
Необходимо заменить батарейки на СВЕЖИЕ (для которых прошло не более года с даты производства), и последним нажать RESET на станции (датчик и станция должны быть настроены на один и то же канал – первый канал есть у всех моделей).

В 90% случаев причины следующие:

А) Подсевшие батарейки (надо заменить батарейки и в станции и в датчике).

Батарейки должны быть новые, свежие, полностью заряженные (под нагрузкой должны выдавать больше 1,5В). В этом случае связь с датчиком, будет устойчивой, и прослужат около года без замены батарей.
Всегда покупайте батарейки прямо перед заменой и обязательно в магазине (не используйте те, что лежали дома про запас). Перед покупкой смотрите на дату производства или срок годности, указанных на корпусе батареек (надо, чтобы прошло не более года с даты их производства — если указан срок годности, то для обычных алкалиновых батареек оставшийся срок годности должен быть не менее 8-9 лет). В регионах с сильными морозами зимой рекомендуется использовать литиевые батарейки.

Б) Неправильно проведена процедура подключения датчика:

1) Установите на датчике канал (1-й есть у всех моделей).
2) Вставьте свежие батарейки
3) Нажмите RESET на датчике
4) Нажмите RESET на основном устройстве. Только после этого RESETа на станции станция начнет поиск датчиков. Поиск длится 2 минуты. Если датчик так и не был найден, то еще раз нажмете этот RESET на станции.(или батарейки не полностью заряжены, и их надо заменять).

С) Станция и датчик настроены на разные каналы:

1) Установить на датчике и станции 1-й канал (1-й канал есть у всех моделей с внешними датчиками).

 

Если станция иногда теряет датчик и впоследствии находит его, то это не является браком: датчик передает сигнал в отрытом для всех диапазоне частот 433 МГц, в котором работают и другие приборы, создающие иногда помехи.

2. Периодически сбивается время.

Неправильно настроена функция радио-контроля времени: В настройках временной зоны надо задать число, равное разнице местного времени и времени в Германии. Либо отключить эту функцию (см. инструкцию) – 3 секунды нажать и удерживать кнопку «ВНИЗ». (для включения этой функции – нажать и удерживать кнопку «ВВЕРХ»)

А) В моделях EW91, EW92, EW93, EW98 эта функция не отключается: необходимо правильно настроить зону. Или попробовать перевести переключатель EU/UK (Европа/Англия, обычно находится в отсеке батареек) в положение UK (из Англии больше шансов, что сигнал не дойдет до стации)

В) В моделях TW369 и TW223 не предусмотрена возможность изменения временной зоны. Как отключить:
TW369:
Долгое (8-10 сек) нажатие на кнопку RECEIVE (в отсеке батареек) ВКЛЮЧАЕТ (на экране рядом с секундами появляется значок антенны с волнами) или ВЫКЛЮЧАЕТ (значок с экрана исчезает) функцию синхронизации времени.
TW223:

Выключение синхронизации времени – долгое нажатие кнопки SNOOZE (8 – 10 сек, не обращать внимание на писк, пока не исчезнет с экрана значок антенны)
Включение – короткое нажатие на кнопку RECEIVE

3. Вместо значения атмосферного давления показывает «ХХХХ».

В данном случае надо заменить элементы питания.

4. Вместо цифрового значения параметра показывает «LL».

«LL» (Low) отображается при слишком низком значении измеряемого параметра.

5. Вместо цифрового значения параметра показывает «HH».

«HH» (High) отображается при слишком высоком значении измеряемого параметра.

6. Некорректные показания температуры

Изделия являются устройствами потребительского (не профессионального) назначения. Они не проходят поверку на точность, и для них не нормируется класс точности и максимально допустимая погрешность (поэтому в характеристиках устройств такие параметры не указаны). Из практики, показания могут отличаться от истинного значения на 1,5-2 градуса, а на некоторых участках и больше. Т.е. расхождения показаний внутреннего и внешнего датчика могут достигать 3-4 градусов. Наиболее точные показания начинаются через 24 часа после помещения датчиков в конкретное место.

7. Некорректные показания влажности.

Изделия являются устройствами потребительского (не профессионального) назначения. Они не проходят поверку на точность, и для них не нормируется класс точности и максимально допустимая погрешность (поэтому в характеристиках устройств такие параметры не указаны). Из практики, показания могут отличаться от истинного значения на 8-10%, а на некоторых участках и больше. Т.е. расхождения показаний внутреннего и внешнего датчика могут достигать 16-20%. Наиболее точные показания начинаются через 24 часа после помещения датчиков в конкретное место.

Минимальный предел диапазона измерений начинается с 25%. При текущей влажности равной 25% и ниже (вне диапазона измерения) показания устройства совершенно недостоверные (может отображаться даже 2%, когда сигнал совсем слабый, или «LL»).
Такие жалобы обычно начинают возникать у клиентов зимой, когда в наших квартирах при включенном центральном отоплении влажность обычно бывает на уровне 18-22% (не больше 23%, если не включен увлажнитель). Сенсор пересыхает и со временем выдает «нулевой» сигнал. Станция 0 отобразить не может – отображается, как правило, 2-4%. Это меньше нижнего предела измерений – надо или купить увлажнитель (комфортная влажность 40-70%) или дожидаться лета.
Это не является неисправностью.

8. Некорректный прогноз погоды

Данные прогноза не должны совпадать с текущей погодой. Это всего лишь прогноз, что будет через 12-24 часа в радиусе 30 км. И точность прогноза не 100%. Прогноз осуществляется на основании динамики изменения атмосферного давления.

9. Не работает подсветка

Смотреть инструкцию. Подсветка экрана, предусмотрена не во всех устройствах OregonScientific

• Должна быть кнопка со словом “Light”.

10. Не включается проекция

  • В устройствах OS с функцией проекционных часов, может быть предусмотрено несколько режимов отображения проекции:
    В устройствах, которых присутствует световой датчик (см. инструкцию, например, в RMR329P, BAR339P), проекция включается, только при недостаточной освещенности помещения, в котором находится устройство.
  • Постоянная проекция возможна только при питании от сети. Для этого необходимо подключить блок питания к Устройству, на обратной стороне устройства кнопку “PROJECTION” передвинуть в положение ON.
  • При использовании часов от батареек возможна только временная проекция. Для этого надо кнопку “PROJECTION” передвинуть в положение OFF. Таким образом проекция времени, будет отображаться на поверхности в течении 8 секунд только при нажатии кнопки LIGHT/ PROJECTION (обычно сверху часов).

11. Приобретенный отдельно внешний датчик не работает со станцией

Продаваемые отдельно внешние датчики совместимы не со всеми моделями устройств.
THGN132N и THWR288 совместимы с моделями: BAR206, BAR208, BAR386, BAR388, BAR800, BAR801, BAR806, BAR808, RAR500, BAR339P, BAR339DP, DP200, RMR329P, RMR391P, RRM902

THGR810 и UVN800 совместимы с моделями: WMR200, WMR88, JW102, LW301

EW99 совместим с моделями: CW101, EW91, EW92, EW93, EW98

Дополнения:

Часто клиенты не смогли разобраться, как правильно эксплуатировать устройство. Наиболее часто встречающиеся вопросы от покупателей:

1. Погодная станция не связывается с датчиком.

Станция ищет датчик только первые 2 минуты после включения или нажатия на станции RESET

Основное условие: датчик и станция должны быть настроены на один и тот же канал (см. инструкцию).

2. Часы отстают на 1-2 часа.

Смотреть инструкцию.
Это не является дефектом. Устройства Oregon Scientific имеют функцию радиоуправляемые часы, настраиваемые на сигнал точного времени в Европе. Из-за разницы в часовых поясах, они начинают отображать показания европейского времени.
• В моделях, которые позволяют настроить корректировку по часовому поясу (см. инструкцию) надо выставить необходимое значение.
• В моделях, где нет функции выставления часового пояса, радиоуправление часов надо отключить (см. инструкцию).

3. Неустойчивая связь между базовым устройством и выносным датчиком. Блеклый экран.

В данном случае надо заменить элементы питания на свежие (для которых прошло не более года с даты производства)

4. Претензии покупателя на точность прогноза погоды.

Для повышения качества прогноза погоды, устройству необходимо собрать некоторую статистику по изменению атмосферного давления в течении хотя бы 7 суток. Пиктограмма прогноза погоды отображает прогноз погоды на ближайшие 12- 24 часа в радиусе 30 км. Точность прогноза не менее 75%. Встроенный в базовое устройство процессор отображает прогноз погоды на основании статистики изменения давления за предыдущие 24 часа, за предыдущие 7 суток и за предыдущие 10 лет (статистика за 10 лет «зашита» в устройство) .
Пиктограмма не отображает фактическую погоду (ту, которая сейчас за окном).

5. Не работает подсветка.

• Смотреть инструкцию. Подсветка экрана, предусмотрена не во всех устройствах OregonScientific
• Должна быть кнопка со словом “Light”.

6. Пищит при срабатывании функции предупреждение о заморозках!

Надо поменять канал работы датчика на 2-й или на 3-й. Так как предупреждение о заморозках срабатывает только при получении данных с 1-ого канала. Все остальные функции устройства будут работать!