• Yii Как избежать дублирование методов в классах?

    DieZz
    @DieZz
    Как мне видится - самый логичный вариант сделать отдельный класс, который будет возвращать имя статуса. Это может быть хелпер, компонент и все что угодно, в зависимости от специфики вашей бизнес логики. Например
    interface HasStatus
    {
        public const STATUS_NOT_PAID = 0;
        public const STATUS_PAID     = 1;
        public const STATUS_CANCEL   = 3;
    
        public function getStatus(): int;
    }
    
    class StatusHelper
    {
        /**
         * Статистический метод получения списка статусов
         *
         * @return array
         */
        public static function getStatusList()
        {
            return [
                HasStatus::STATUS_NOT_PAID => 'Не оплачено',
                HasStatus::STATUS_PAID     => 'Оплачено',
                HasStatus::STATUS_CANCEL   => 'Отменена',
            ];
        }
    
        public function getStatusName(HasStatus $entity): string
        {
            ArrayHelper::getValue(self::getStatusList(), $entity->getStatus());
        }
    }

    Соответственно все ваши модельки должны имплементирвать интерфейс HasStatus. Таким образом вся бизнес логика находится в одном месте и отвязана от БД
    Ответ написан
    1 комментарий
  • Когда в GET запросе передается параметр из русских символов, то скрипт не отрабатывает. В чем причина?

    DieZz
    @DieZz
    Проблема в том, что данный урл невалидный (
    RFC 1738
    ), т.е. содержит русские символы. В вашем случае ссылка должны выглядеть примерно так
    https://мойсервер/telegrambot/file.php?apibot=24953021_______Pnjwywdkg&chatid=-1003333102111&document=%D0%9F%D1%80%D0%BE%D0%B4%D0%B0%D0%B6%D0%B8_%D0%BC%D0%B5%D1%81%D1%8F%D1%86_%D0%BC%D0%B0%D0%B9.xls

    Беглый поиск по гуглу говорит что в 1С есть функция КодироватьСтроку()
    Ответ написан
    Комментировать
  • Как подключить Adldap2 в Yii2?

    DieZz
    @DieZz
    Если вопрос еще актуален, могу поделится своей реализацией
    В первую очередь я создал компонент который является обореткой для Adldap
    spoiler
    <?php
    
    namespace app\components;
    
    use Adldap\Adldap;
    use Adldap\Auth\BindException;
    use Adldap\Auth\PasswordRequiredException;
    use Adldap\Auth\UsernameRequiredException;
    use Adldap\Connections\ProviderInterface;
    use Adldap\Models\Group;
    use Adldap\Models\Model;
    use Adldap\Models\User;
    use app\components\interfaces\ExternalAuthProviderInterface;
    use Illuminate\Support\Collection;
    use yii\base\Component;
    
    /**
     * Class LdapService
     * Wrapper to work with LDAP package.
     *
     * @package app\components
     */
    class LdapService extends Component implements ExternalAuthProviderInterface
    {
        /**
         * Account suffix.
         *
         * @var string
         */
        public $accountSuffix = '';
        /**
         * List of domain controllers.
         *
         * @var array
         */
        public $domainControllers = [];
        /**
         * Base DN.
         *
         * @var string
         */
        public $baseDn;
        /**
         * Domain admin user name.
         *
         * @var string
         */
        public $adminUserName;
        /**
         * Domain admin password.
         *
         * @var string
         */
        public $adminPassword;
        /**
         * Connection provider to the AD.
         *
         * @var ProviderInterface
         */
        private $provider;
    
        /**
         * Attempt to login in domain.
         *
         * @param string $login    login.
         * @param string $password password.
         *
         * @throws BindException if there are connections errors.
         * @throws PasswordRequiredException
         * @throws UsernameRequiredException
         *
         * @return bool
         */
        public function attempt(string $login, string $password): bool
        {
            return $this->getProvider()
                ->auth()
                ->attempt($login, $password);
        }
    
        /**
         * Find user in the AD by login(account name).
         *
         * @param string $login login/account name.
         *
         * @throws \Adldap\Models\ModelNotFoundException
         * @throws BindException
         * @throws \InvalidArgumentException
         * @return User|Model
         */
        public function findUserByLogin(string $login): User
        {
            return $this->getProvider()
                ->search()
                ->users()
                ->where('samaccountname', '=', $login)
                ->firstOrFail();
        }
    
        /**
         * Find user in the AD by full name.
         *
         * @param string $username users full name.
         *
         * @throws \Adldap\Models\ModelNotFoundException
         * @throws BindException
         * @throws \InvalidArgumentException
         * @return User|Model
         */
        public function findUserByFullName(string $username): User
        {
            return $this->getProvider()
                ->search()
                ->users()
                ->where('cn', '=', $username)
                ->firstOrFail();
        }
    
        /**
         * Returns list of all group in the AD.
         *
         * @throws BindException
         * @return Collection|Group[]
         */
        public function getAllGroups(): Collection
        {
            return $this->getProvider()
                ->search()
                ->groups()
                ->get();
        }
    
        /**
         * Returns configured AD provider.
         *
         * @throws BindException
         * @return ProviderInterface
         */
        private function getProvider(): ProviderInterface
        {
            if (null === $this->provider) {
                $ad = new Adldap($this->getConfig());
                $this->provider = $ad->connect('default');
            }
    
            return $this->provider;
        }
    
        /**
         * Returns config to connect to the ldap domain.
         *
         * @return array
         */
        private function getConfig(): array
        {
            return [
                'default' => [
                    'domain_controllers' => $this->domainControllers,
                    'base_dn'            => $this->baseDn,
                    'admin_username'     => $this->adminUserName,
                    'admin_password'     => $this->adminPassword,
                    'account_suffix'     => $this->accountSuffix,
                ],
            ];
        }
    }



    Теперь этот компонент необходимо подключить через конфиг приложения
    spoiler
    'components' => [
            ...
            'ldap' => [
                'class'             => \app\components\LdapService::class,
                'accountSuffix'     => '@test',
                'domainControllers' => ['192.168.1.1'],
                'baseDn'            => 'DC=admin',
                'adminUserName'     => 'admin',
                'adminPassword'     => 'password',
            ],
        ],



    И далее уже можем использовать его в нашем коде
    $user = \Yii::$app->get('ldap')->findUserByLogin('someLogin');
    Ответ написан
    Комментировать
  • YII2 добавить товар в разные категории?

    DieZz
    @DieZz
    Yii2 это не движок, а фреймворк. Касательно вашего вопроса - проблема тут не уровня фреймворка, а уровня проектирования БД. Тут достаточно создать три таблицы
    products
    ----------
    id
    name
    ...
    
    categories
    ------------
    id
    name
    ...
    
    products_categories
    ------------------------
    product_id
    category_id

    В этом случае каждый товар можно связать с большим числом категорий. Прочитайте про связи "многие ко многим"
    Ответ написан
    1 комментарий
  • MY SQL для MacOs 10.7 и выше?

    DieZz
    @DieZz
    docker или vagrant вам в помощь
    Ответ написан
    Комментировать
  • Как грамотно и красиво писать код php?

    DieZz
    @DieZz
    Все уже давно придумано https://www.php-fig.org/psr/psr-2/
    Ответ написан
    Комментировать
  • After downloading the file from the repository, an error occurred. How i can solve this problem?

    DieZz
    @DieZz
    You might need to run composer install first
    Ответ написан
    Комментировать
  • Как в PHP открыть удалённую директорию?

    DieZz
    @DieZz
    Монтировать самый разумный вариант. Если не нравится то можно использовать какой либо клиент, например https://github.com/icewind1991/SMB
    Ответ написан
    Комментировать
  • Что происходит во время долгой авторизации некоторых сайтов?

    DieZz
    @DieZz
    Скорее всего есть несколько причин:
    1. Используется сложный алгоритм хеширования пароля. Пароль всегда хешируется чтобы сравниться с хешем который есть в БД. Например php.net/manual/en/function.password-hash.php при большом значении cost считается довольно долго.
    2. Поскольку сервисы крупные, то возможно есть временные(из-за большого числа запросов) и сетевые задержки при работе с различными серверами приложения.
    Ответ написан
    Комментировать
  • Как заключить повторяющийся код в функцию?

    DieZz
    @DieZz
    Проблема в области видимости. Ознакомьтесь php.net/manual/ru/language.variables.scope.php
    Упрощенно ваша функция не видит переменных $width, $image и т.д. Эти переменные надо передавать как аргументы функции
    function someFunction($width)
    {
        return ++$width;
    }

    либо расширять область видимости до глобальной
    function someFunction()
    {
        global $width;
        // do something with $width
    }

    что в принципе не очень хорошо. Вариант с аргументами функции предпочтительнее, но в вашем случае их получится много, что тоже нехорошо
    Ответ написан
  • Как грамотно написать программу для тестирования?

    DieZz
    @DieZz
    Посмотрите паттерн State Machine. Есть уже готовые реализации, например https://github.com/jakesgordon/javascript-state-machine
    Ответ написан
    Комментировать
  • API php, Как правильно отдать данные?

    DieZz
    @DieZz
    Лучше всего имплементировать интерфейс JsonSerializable, например вот так
    class BlogPost extends Post implements JsonSerializable {
        //...
    
       public function jsonSerialize() {
            return [
                'title' => $this->title,
                'attachments' => $this->attachments,
                 ...
            ];
        }
    }


    дальше вы легко отправлять ответ:
    return json_encode($blogPost);
    Ответ написан
    Комментировать
  • Условие для Assets в Yii2?

    DieZz
    @DieZz
    Используйте AssetBundle и метод init() в нем, например:
    <?php
    
    namespace app\assets;
    
    use yii\web\AssetBundle;
    
    class AppAsset extends AssetBundle
    {
        public function init()
        {
            $format = 'theme/assets/global/plugins/date/locales/dater.%s.min.js';
            $this->js[] = sprintf($format, \Yii::$app->language);
        }
    }
    Ответ написан
    Комментировать
  • Как реализовать middleware-like логику в Yii2?

    DieZz
    @DieZz
    Используйте поведения (behaviors). Например в Yii из коробки есть такая штука:
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        $behaviors['authenticator'] = [
            'class' => HttpBearerAuth::className(),
        ];
        
        return $behaviors;
    }


    Если хотите свою логику для проверки токена, то создайте класс который будет имлпементировать интерфейс yii\filters\auth\AuthInterface у указывайте его в поведении. В случае ошибки авторизации бросайте UnauthorizedHttpException
    Ответ написан
    6 комментариев
  • Как проверить соответствие экземпляра ActiveRecord определенному интерфейсу?

    DieZz
    @DieZz
    Используйте интерфейс для типизации модели и используйте явное указание типа аргумента в нужном методе. Например:
    <?php
    
    interface UserInterface
    {
        public function getFirstName();
    
        public function getLastName();
    
        public function getLogin();
    }
    
    /**
     * Class User
     *
     * @property string $firstName
     * @property string $lastName
     * @property string $login
     */
    class User extends \yii\db\ActiveRecord implements UserInterface
    {
        ...
    
        public function getFirstName()
        {
            return $this->firstName;
        }
    
        public function getLastName()
        {
            return $this->lastName;
        }
    
        public function getLogin()
        {
            return $this->login;
        }
    
    }
    
    class TestController
    {
        /**
         * Здесь явно указываем тип переменной, которую ожидаем. Если мы передадим
         * объект, который не имплиментирует нужный интерфейс, то будет ошибка.
         *
         * @param UserInterface $user
         */
        public function actionTest(UserInterface $user)
        {
            $name = $user->getFirstName();
            ...
        }
    }
    Ответ написан
    Комментировать
  • Как правильно реализовать динамическую маршрутизацию в Laravel?

    DieZz
    @DieZz
    Я делал так:
    Route::any('{page}', 'PageHandlerController@handle')->where('page', '^(?!admin).*');

    Где контроллер доставал из базы нужную страницу. Примерно так:

    class PageHandlerController extends Controller
    {
        public function handle($page)
        {
            $page = CustomPage::where('url', $page)->first();
    
            if (!$page) {
                abort(404);
            }
    
            // тут делаем все что нам угодно
        }
    Ответ написан
  • Как в Yii2 ActiveForm сделать AJAX отправку и обработку данных?

    DieZz
    @DieZz
    Примерно так:
    $form = ActiveForm::begin([
        'id' => 'form-input-example',
        'options' => [
           'onsubmit' => 'sendAjax(this, myAction)'
        ],
    ]);
    ...

    Метод sendAjax:
    var myAction = function (response) {
        //Делаем то, что нам нужно с ответом
        console.log(response);
    }
    
    function sendAjax(form, callback) {
        $.ajax({
            method: 'post',
            url: '/test',
            dataType: 'json',
            data: $(form).serialize()
        }).done(function (response) {
            callback(response);
        })
    
       //Возвращаем false чтобы форма не отправилась
       return false;
    }

    Код не проверял, но теоретически должно работать.
    Ответ написан
    Комментировать
  • Можно ли запскать веб контроллер yii2, как cron задачу?

    DieZz
    @DieZz
    Используйте консольное приложение
    Ответ написан
    Комментировать
  • Как функцию в php переименовать?

    DieZz
    @DieZz
    Никак. В функции своя область видимости, изолированная от глобальной. Когда инклюдите файл, весь его код наследует ту же область видимости переменных, что и строка, на которой произошло включение, а это область видимости функции, которая, как я писал выше, изолированна от глобальной. Смотрите пример №2 из документации
    Ответ написан
    Комментировать
  • Есть ли возможность отключить exception?

    DieZz
    @DieZz
    Зачем отключать исключения? Они как раз говорят, что что-то идет не так. Научитесь использовать их правильно и программировать станет проще
    try {
        //Тут что то делаем с сокетом
        fsockopen();
    } catch (ErrorException $e) {
        //Что то пошло не так - обработаем исключение, например, так:
       echo $e->getMessage();
    }

    Тогда выполнение кода не прервется, и мы будем знать что произошло и как это обрабатывать.
    Ответ написан