Задать вопрос
  • Почему отсутствие элемента массива вызывает ошибку?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Используйте null-оператор (может он по-другому называется, не помню):

    <?= $_POST['title'] ?? '' ?>

    Или проверяйте наличие ключа

    <?= array_key_exists('title', $_POST) ? $_POST['title'] : '' ?>
    Ответ написан
    1 комментарий
  • Как правильно оформить проверку в middleware?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    $userId = Auth::user()->id; // Переменную плохо назвали. Это ID, а не пользователь
    $editor = Pass::where('user_id', $userId)->first(); // А здесь редактор, не ID. Может быть NULL если не найдено.
    // Нужно проверить, нашлась ли запись и совпали ли ID
    //if ($editor && $userId == $editor->user_id) {        }
    
    // Но исходя из условия запроса, если запись нашлась, то ID уже совпали
    // Значит достаточно такой проверки:
    if ($editor) {        }
    Ответ написан
    1 комментарий
  • Как исправить @import scss в vue.js?

    delphinpro
    @delphinpro
    frontend developer
    Зачем вы так странно импортируете?
    Прямо в index.js import "./assets/scss/style.scss";
    Ответ написан
    Комментировать
  • Как работать с WSDL / SOAP в PHP?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Я использовал этот пакет https://github.com/notfalsedev/laravel-soap

    example

    class SoapController extends Controller
    {
        /** @var \Artisaninweb\SoapWrapper\SoapWrapper */
        protected $soap;
    
        /** @var \Artisaninweb\SoapWrapper\Client */
        protected $client;
    
        public function __construct(SoapWrapper $soap)
        {
            $this->soap = $soap;
            $this->client = null;
        }
    
        public function getComputers()
        {
            try {
                $clientId = request()->get('clientId', 0);
                $orgId = request()->get('orgId', 0);
                $this->initSoap();
                $response = $this->client->call('GetComps', [
                    [
                        'ClientId' => $clientId,
                        'OrgId'    => $orgId,
                    ],
                ]);
    
                $computers = json_decode($response->GetCompsResult, true);
                return response()->json($computers, 200);
    
            } catch (\Throwable $e) {
                return response()->json([
                    'message' => $e->getMessage(),
                ], 500);
            }
        }
    
        /**
         * @throws \Exception
         */
        protected function initSoap()
        {
            $clientName = 'some_name';
            $wsdl = config('app.soap_wsdl');
            if (!$wsdl) throw new \Exception('Invalid wsdl');
            $version = $this->getSoapVersion();
            $this->soap->add($clientName, function (SoapService $service) use ($wsdl, $version) {
                $service
                    ->wsdl($wsdl)
                    ->options(['soap_version' => $version]);
            });
    
            $this->client = $this->soap->client($clientName, function ($client) { return $client; });
        }
    
        /**
         * @return int
         * @throws \Exception
         */
        protected function getSoapVersion()
        {
            switch (config('app.soap_version')) {
                case '1.1':
                    return SOAP_1_1;
                case '1.2':
                    return SOAP_1_2;
                default:
                    throw new \Exception('Invalid SOAP version');
            }
        }
    }
    Ответ написан
    Комментировать
  • Как подключить класс через use?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Могу ошибиться немного, но в целом так:
    use App\Models\Route;
    use App\Controllers\TestController;
    
    return [
        new Route('/test/uri', TestController::class, 'testFunc')
    ];


    Когда вы делаете new $elem->controller, то получается new TestController, без неймспейса.

    Статическое свойство ::class содержит полное имя класса в виде строки.
    Поэтому в моем варианте у вас будет получаться как раз
    new \App\Controllers\TestController

    Ну и можно строкой писать в роутах полное имя класса

    return [
        new Route('/test/uri', '\\App\\Controllers\\TestController', 'testFunc')
    ];


    Но это менее удобно, как мне кажется.
    Ответ написан
    1 комментарий
  • Не получается найти ссылку Laravel Dusk, что не так?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Во-первых, у вас кнопка не являеттся непосредственным потомком #content, потому и не находится. Убрать угловую скобку из селектора.

    Во-вторых, если у кнопки есть идентификатор, то она по определению единственная на странице, а значит достаточно просто ->click('#add-baseavto-btn');
    Ответ написан
    3 комментария
  • Почему при сортировке 1 меньше, чем true?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    При приведении типов (во время операции вычитания) true приводится к 1. Эти два значения равны, и в результирующем массиве они следуют в том же порядке. что и в исходном. Можете проверить, поменяв true и 1 местами.
    Ответ написан
    Комментировать
  • Как "перепрошить" мозг будущему программисту?

    delphinpro
    @delphinpro
    frontend developer
    Ну, ок, допустим, беру какую-нибудь задачу. Прочёл текст. А дальше-то что? Я не знаю как подойти к решению задачи, с чего начать, что вообще делать и чем закончить.

    Анализ, декомпозиция.
    Разбивайте общие задачи на более мелкие, элементарные.

    Задача: выпить кофе.

    Разбиваем на составляющие:
    • Достать турку
    • Налить воды
    • Добавить кофе
    • Сварить
    • Попить

    Подзадачу "Сварить" делим на еще более мелкие:
    • Зажечь газовую плиту
    • Поставить турку на конфорку
    • Довести до кипения

    Задачу "Зажечь газовую плиту" снова делим на составляющие:
    • Взять спички
    • Чиркнуть о коробок
    • Открыть подачу газа в конфорку
    • Поднести спичку к конфорке


    И т.д. До самых элементарных уровней.
    Ответ написан
    2 комментария
  • Поиск на сайте с помощью другого сайта?

    delphinpro
    @delphinpro
    frontend developer
    Комментировать
  • Как устроена обработка классов в PHP?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Переменная $constraints принадлежит классу, не объекту.
    Вы меняете ее вызовом A::noConstraints()
    Теперь эта переменная false
    Потом вы создаете объект на основе класса в котором эта переменная изменена.
    По-моему всё логично.

    UPD
    Даже не так.

    Неважно когда вы создаете объект.
    Важно то, что в этом объекте вы обращаетесь к переменной класса, после ее изменения

    С таким кодом должен быть аналогичный результат.

    $b = new B;
    $b->show(); // true
    
    A::noConstraints(function() use($b) {
        $b->show(); // false
    });
    Ответ написан
  • Как отобрать параметры TV в отдельных вкладках?

    delphinpro
    @delphinpro
    frontend developer
    Тут либо в настройках (вкладка "Интерфейс и представление") стоит настройка группировки TV в новых табах. Тогда просто свои TV поместите в новую группу.
    60591c55a9a11266255772.png

    Либо используется дополнение для кастомизации админки. Устаревший ManagerManager или новый TemplateEdit3.
    Тогда, соответственно, нужно настраивать расположение новых TV в конфигах этих дополнений.
    Ответ написан
    Комментировать
  • Какой вариант записи правильный, li + li или li:last-child?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Что значит, результат одинаковый?

    li + li {} Выбирает все элементы кроме первого.
    li:last-child {} Выбирает только последний элемент.

    Дополню. Может показаться, что первый вариант идентичен такому:
    li:not(:first-child) {}
    Да, в частном случае. Поэтому стоит быть осторожным. Например в разметке
    div > (a + p + p + p)
    селектор p + p выберет последние два параграфа
    а селектор p:not(:first-child) - все параграфы.
    Ответ написан
  • Что значит defineComponent?

    delphinpro
    @delphinpro
    frontend developer
    https://v3.vuejs.org/api/global-api.html#definecom...

    Вольный перевод:
    Функция ничего не делает, только возвращает переданный объект.
    Нужна для поддержки TypeScript и IDE (автокомплит и прочее)
    Ответ написан
    Комментировать
  • Как правильно организовать код в таком случае?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    В общем, если вам нужно прикрутить логирование, просто установите себе пакет https://github.com/php-fig/log
    И не отвлекайтесь на изобретение велосипеда. Займитесь действительно полезной работой - покрытием логами.
    Ответ написан
  • Как правильно собрать 2 разных js в webpack?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    package.json
    {
        "private": true,
        "scripts": {
            "site:development": "mix",
            "site:watch": "mix watch",
            "site:hot": "mix watch --hot",
            "site:production": "mix --production",
            "dashboard:watch": "cross-env TARGET=dashboard mix watch",
            "dashboard:hot": "cross-env TARGET=dashboard mix watch --hot",
            "dashboard:production": "cross-env TARGET=dashboard mix --production"
        },
        "devDependencies": {
            "browser-sync": "^2.26.14",
            "browser-sync-webpack-plugin": "^2.2.2",
            "chalk": "^4.1.0",
            "cross-env": "^7.0.3",
            "dotenv": "^8.2.0",
            "laravel-mix": "^6.0.13",
            "resolve-url-loader": "^3.1.2",
            "sass": "^1.32.8",
            "sass-loader": "^10.1.1"
        },
        "dependencies": {}
    }

    webpack.mix.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    const path = require('path');
    const dotenv = require('dotenv');
    /** @type {Chalk} */
    const chalk = require('chalk');
    
    const dotEnvLocation = path.resolve('./.env');
    dotenv.config({ path: dotEnvLocation });
    
    const WATCH = process.argv.includes('--watch');
    const HOT = process.argv.includes('--hot');
    const localDomain = process.env.LOCAL_DOMAIN ?? 'localhost';
    const target = process.env.TARGET ?? 'site';
    
    let browserSyncPort = 3000;
    let hmrPort = 8088;
    
    const logs = {
        mode    : WATCH ? chalk.red('WATCH') : HOT ? chalk.red('HOT') : 'None',
        domain  : process.env.LOCAL_DOMAIN ?? chalk.red(localDomain),
        frontend: process.env.FRONTEND_DIST ?? chalk.red(process.env.FRONTEND_DIST),
        backend : process.env.BACKEND_DIST ?? chalk.red(process.env.BACKEND_DIST),
    };
    
    console.log(chalk.cyan('Local domain:  ') + logs.domain);
    console.log(chalk.cyan('Location .env: ') + dotEnvLocation);
    console.log(chalk.cyan('Mode:          ') + logs.mode);
    console.log(chalk.cyan('Public paths:'));
    console.log(chalk.cyan('  Frontend:    ') + logs.frontend);
    console.log(chalk.cyan('  Backend:     ') + logs.backend);
    
    if (target === 'dashboard') {
        browserSyncPort = process.env.BACKEND_LOCAL_PORT ?? 3000;
        hmrPort = process.env.BACKEND_HMR_PORT ?? 8088;
        require('./webpack-dashboard.mix.js');
    }
    
    if (target === 'site') {
        browserSyncPort = process.env.FRONTEND_LOCAL_PORT ?? 3001;
        hmrPort = process.env.FRONTEND_HMR_PORT ?? 8089;
        require('./webpack-site.mix.js');
    }
    
    /*==
     *== Customize options
     *== ======================================= ==*/
    
    mix.version();
    
    mix.disableSuccessNotifications();
    
    if (!HOT && WATCH) {
        mix.browserSync({
            proxy    : localDomain,
            startPath: target === 'site' ? '/' : '/admin',
            browser  : ['chrome'],
            notify   : false,
            port     : browserSyncPort,
        });
    }
    
    mix.options({
        clearConsole: false,
        hmrOptions  : {
            host: 'localhost',
            port: hmrPort,
        },
    });
    
    const webpackResolveRules = {
        extensions: ['*', '.wasm', '.mjs', '.js', '.jsx', '.json', '.vue'],
        alias     : {
            '@': path.join(__dirname, 'resources/js'),
        },
    };
    
    mix.sourceMaps(false, 'source-map');
    
    if (!mix.inProduction()) {
        mix.webpackConfig({
            output : { devtoolModuleFilenameTemplate: '[resource-path]' },
            resolve: webpackResolveRules,
        });
    } else {
        mix.webpackConfig({
            resolve: webpackResolveRules,
        });
    }

    webpack.mix.site.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    
    const HOT = process.argv.includes('--hot');
    
    if (!process.env.FRONTEND_DIST) throw Error;
    
    mix.setPublicPath(`public/${process.env.FRONTEND_DIST}`);
    if (!HOT) mix.setResourceRoot(`/${process.env.FRONTEND_DIST}`);
    
    mix.js('resources/js/app.js', 'js');
    
    mix.sass('resources/scss/app.scss', 'css');
    
    mix.extract();

    webpack.mix.dashboard.js
    /** @type {Api} */
    const mix = require('laravel-mix');
    
    const HOT = process.argv.includes('--hot');
    
    if (!process.env.BACKEND_DIST) throw Error;
    
    mix.setPublicPath(`public/${process.env.BACKEND_DIST}`);
    if (!HOT) mix.setResourceRoot(`/${process.env.BACKEND_DIST}`);
    
    mix.js('resources/dashboard/js/main.js', 'js');
    
    mix.sass('resources/dashboard/scss/main.scss', 'css');
    
    mix.extract();

    .env
    LOCAL_DOMAIN=delphinpro.local
    FRONTEND_LOCAL_PORT=3000
    FRONTEND_HMR_PORT=8003
    FRONTEND_DIST=dist/frontend
    BACKEND_LOCAL_PORT=3004
    BACKEND_HMR_PORT=8004
    BACKEND_DIST=dist/backend

    config/app.php
    <?php
    return [
        // .....
        'frontend' => [
            'dist' => env('FRONTEND_DIST'),
        ],
        'backend' => [
            'dist' => env('BACKEND_DIST'),
        ],
    ];

    *.blage.php
    <link href="{{ mix('css/app.css', config('app.frontend.dist')) }}" rel="stylesheet">
    <script src="{{ mix('js/app.js', config('app.frontend.dist')) }}"></script>
    Ответ написан
    Комментировать
  • Как сделать разные изображения для метатега og:image через php?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    $social_tags['image'] =  $xfieldsdata['screens']
      ?? $xfieldsdata['poster-link']
      ?? ( $xfieldsdata['poster'] ? "/uploads/posts/".$xfieldsdata['poster'] : '/link/to/default.jpg' );
    Ответ написан
    1 комментарий
  • Как прибавлять к сегодняшнему числу еще 7?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    Есть офигительная библиотека momentjs

    moment().add(7, 'days');
    Ответ написан
  • Как функцию stilys скомпилить в sass?

    delphinpro
    @delphinpro Куратор тега Sass
    frontend developer
    Здесь разница только в присваивании. В стайлусе знак "равно", в сасс - "двоеточие"
    $font-size-base: 12px
    $line-height-base: 16px
    text-margin($top, $right, $bottom, $left, $font-size: $font-size-base, $line-height: $line-height-base)
      if $top != 0
        $top: $top - ($line-height - $font-size) / 2
    
      if $bottom != 0
        $bottom: $bottom - ($line-height - $font-size) / 2
    
      margin: $top $right $bottom $left


    Ах, да. Еще как-то определяется функция миксин. Я не помню.
    В нормальном sass это было бы так:

    @mixin text-margin($top, $right, $bottom, $left, $font-size: $font-size-base, $line-height: $line-height-base) {
    
    }
    Ответ написан
    2 комментария
  • Как организовать стили в большом проекте?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Разбивайте файлы на отдельные блоки. Создайте просто файлы critical.scss и main.scss. В main подключайте всё, в критикал только то, что необходимо для первого экрана.
    Таким образом все ваши стили в основном файле будут организованы как обычно, но вы сможете создавать разные файлы critical для разных страниц.
    Ответ написан
    Комментировать
  • Можно ли использовать absolute в верстке письма?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    Нарезаете картинку на куски. Нужные куски оборачиваете в ссылки.
    Раскладываете все это по ячейкам таблицы.
    Все в лучших традициях верстки прошлого века =))
    Но зато, точно будет отображаться более или менее нормально.

    Насчет огромности картинки. Рекомендованная ширина письма — не более 600-780 пикс.
    Ответ написан
    Комментировать