Задать вопрос
  • Как написать на Symfony EventSubscriber который бы перехватывал запись в бд?

    @Flying
    Конечно можно, просто нужно использовать не Symfony event listener, а Doctrine event listener, там есть всё необходимое.
    Ответ написан
    Комментировать
  • Как перестроить миксин?

    @Flying
    В целом всё очень просто:
    @each $query in $queries {
        @media (max-width: #{$query}) {
            @for $i from 1 through 6 {
                h#{$i} {
                  font-size: nth($sizes, $i);
                }
            }
        }
    }

    Однако лучше хранить размеры в map'е, это позволит упростить код:
    $sizes: (
      h6: $fzh6, 
      h5: $fzh5, 
      h4: $fzh4, 
      h3: $fzh3, 
      h2: $fzh2, 
      h1: $fzh1
    );
    
    @each $query in $queries {
        @media (max-width: #{$query}) {
            @each $tag, $size in $sizes {
                #{$tag} {
                  font-size: $size;
                }
            }
        }
    }
    Ответ написан
  • Как подсчитать при помощи php количество дней от рождения человека?

    @Flying
    $birthday = 19880315;
    $age = (new DateTime('now'))->diff(DateTime::createFromFormat('Ymd',(string)$birthday), true)->y;
    Ответ написан
    Комментировать
  • Doctrine, как задать значение даты по умолчанию?

    @Flying
    Просто проинициализируйте это поле в конструкторе или в обработчике @PrePersist lifecycle event.
    Ответ написан
    Комментировать
  • Правильно ли указывать foreach в репозитории в Symfony?

    @Flying
    Вам стоит взглянуть на различные режимы гидраторов в Doctrine. В частности в вашем случае вы, скорее всего захотите использовать scalar hydration по результатам выборки одного столбца. Вместе с этим режимом очень хорошо работает array_column(), так что ваш метод мог бы выглядеть примерно вот так (в примере идёт выборка столбца email из entity User):
    public function getEmails()
    {
        return array_column($this->getEntityManager()
            ->createQuery('select u.email from User u')
            ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR), 'u_email');
    }

    или, если вам, к примеру, необходима связь между id и email:
    public function getEmails()
    {
        return array_column($this->getEntityManager()
            ->createQuery('select u.id, u.email from User u')
            ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR), 'u_email', 'u_id');
    }
    Ответ написан
    Комментировать
  • Как выложить проект на Symfony 4 на сервер?

    @Flying
    Подробный ответ на ваш вопрос есть в документации Symfony. Также обратите внимание на то что публичный каталог проекта можно поменять, как это делается - описано здесь.

    В целом конечно использовать для Symfony проектов хостинги с фиксированной структурой каталогов - не лучшая идея, к примеру не все из них дают нормальный доступ к консоли. По возможности лучше использовать VPS.
    Ответ написан
    1 комментарий
  • Почему всем так нужен Doctrine, если он много не умеет?

    @Flying
    Doctrine реализует концептуально другой подход к работе с данными, именно в этом её большое преимущество и именно из этого следуют её ограничения.

    Если вы когда-нибудь сталкивались с паттернами проектирования то, возможно, слышали о таком человеке как Мартин Фаулер и о его книге "Patterns of Enterprise Application Architecture". В ней описываются паттерны проектирования enterprise level приложений. В этой книге Фаулер предложил набор паттернов, организующих работу с источниками данных через представление этих данных в виде связанных между собой объектов. В этот набор входят Data Mapper, Identity Map, Unit of Work и множество других паттернов.

    Если идти чуть глубже то суть Doctrine - это возможность работать с данными в базе данных как с обычными объектами. Если задуматься - это открывает невиданные перспективы в обеспечении предсказуемости разработки и поддержки кода проекта т.к. обеспечивает разработчика возможностью абстрагироваться от деталей хранения информации и сосредоточиться на важной части его работы - реализации бизнес-логики проекта. Doctrine же берёт на себя заботу о том чтобы приложение получило нужные данные когда ему это будет нужно, чтобы эти данные были корректно сохранены, чтобы не возникло конфликтов и т.д. и т.п.

    Попробуйте представить себе большой бизнес-проект над которым работают множество людей, в котором есть сотни видов данных, взаимодействующих друг с другом и определены сложные процессы вовлекающие множество видов данных. Разумеется это все можно написать и поддерживать вручную, таких примеров много, вопрос в стоимости подобной работы. Представьте себе необходимость вручную описывать последовательность запросов для сохранения данных в 20 таблиц и необходимость поддерживать корректность этого кода при всех следующих изменений бизнес-требований проекта. Уверен, если после полугода подобной работы вам предложат заменить всё это на одну строку $em->flush() - вы с радостью согласитесь и, возможно, тогда поймёте что даёт Doctrine разработчику.

    Именно из идеи перевода фокуса разработчика с деталей реализации хранилища данных на детали реализации бизнес-логики проекта рождаются ограничения Doctrine. Они могут восприниматься негативно если пытаться воспринимать Doctrine и DQL как урезанный SQL, почему-то возвращающий объекты, а не массивы. Да, разумеется какие-то сложные аналитические запросы вы на DQL не построите, но это только потому что у Doctrine другая цель. Если посмотреть на DQL чуть пристальнее (к примеру на то как в нём описываются join'ы) то можно заметить что Doctrine отталкивается не от того как данные разложены по таблицам, а от того как данные представлены в entities. Это не самое заметное, но очень важное отличие т.к. оно определяет пространство операций над данными. Грубо говоря приведённый вами ifnull() в DQL становится довольно бессмысленной конструкцией т.к. эта функция довольно слабо применима к объектам.

    Разумеется в реальных проектах зачастую бывают задачи которые требуют работы с данными в базе данных за пределами Doctrine, это нормально, ни один инструмент не является всеобъемлющим. Однако описываемые вами "недостатки" Doctrine проистекают скорее от непонимания того что это за инструмент и зачем он нужен, какие задачи он призван решить. Это непонимание устраняется через изучение того с чем вы работаете на более глубоком уровне. Если вы решите устранить его - вы получите в свои руки один из лучших инструментов для работы с данными в бизнес-проектах который только есть в мире PHP и тогда, надеюсь, сможете оценить его по достоинству.
    Ответ написан
    Комментировать
  • Как выполнить команду программно и автоматически ответить на вопросы?

    @Flying
    Если речь идёт о частном случае данной команды - то ответ довольно прост и легко ищется в исходных текстах. Вот как проверяется возможность запуска команды миграции, как видно - здесь используется метод canExecute(), посмотрев в который можно заметить что он контролируется флагом --no-interaction. Более того, банально вызвав help по этой команде можно было бы увидеть ответ на свой вопрос написанный прямым текстом:
    Or you can also execute the migration without a warning message which you need to interact with:
    
        bin/console doctrine:migrations:migrate --no-interaction


    Если же речь идёт об общем подходе к тому как запускать консольные команды которые требуют пользовательского ввода - то здесь ответ довольно находится в документации Symfony. Если посмотреть в исходные тексты ConsoleTester о котором говорится в этом разделе, то видно что основная идея - использование специального input'а. Таким образом решение становится довольно простым:
    1. Получаем и клонируем Kernel
    2. Создаём новый консольный Application
    3. Создаём и конфигурируем ArrayInput
    4. Запускаем приложение с нужным нам input'ом

    Весь основной код для этого можно, очевидным образом, подсмотреть в bin/console самой Symfony.
    Ответ написан
    2 комментария
  • Как резолвит пути Symfony 4?

    @Flying
    Этот путь (а точнее множество путей) указывается в MicroKernelTrait::configureRoutes(). Если быть более точным - то этот trait определяет метод для конфигурирования роутинга, а реальный код (в его стандартном виде) является частью Symfony Flex recipe для symfony/framework-bundle, посмотреть его можно в соответствующем репозитории.

    Если ваш проект создан из symfony/skeleton и, соответственно, использует Symfony Flex, то этот код находится в src/Kernel.php вашего проекта и добавлен он туда именно через recipe.
    Ответ написан
  • Как в SCSS сделать увеличенное значение?

    @Flying
    На самом деле ваш пример почти корректен, только чуть доработать:
    @mixin last-childs {
        @for $i from 7 through 1 {
            &:nth-last-child(#{$i}) {
               margin-left: 40px - 5px * ($i - 1);
            }
        }
    }
    Ответ написан
    1 комментарий
  • Как делать мультикурсор в новом PHPStorm?

    @Flying
    Вот здесь можно почитать обсуждение с разработчиками по данному вопросу. Если вкратце - это настраивается в
    Settings -> Keymap -> Editor Actions -> Rectangular Selection
    Ответ написан
    Комментировать
  • SASS. Компиляция. От чего зависит результат?

    @Flying
    У вас placeholder %gallery__man-flex определён внутри .gallery, таким образом все места где будет использоваться этот placeholder будут наследовать контекст его определения.

    В остальных случаях запись вида &__man означает "расширение текущего селектора", поэтому очевидно добавления контекстного селектора не происходит. Если он нужен - то стоит использовать & &__man
    Ответ написан
    2 комментария
  • Какой наиболее "ремонтопригодный" движок на PHP для интернет-магазина?

    @Flying
    На практике не пробовал, но предположу что неплохим вариантом будет Sylius. Он изначально и целиком построен на Symfony, поэтому с точки зрения архитектуры у него не должно быть проблем, как, например, в Magento где замешаны ZF1, ZF2 и Symfony + куча собственных наработок. Он весьма активно развивается и вокруг него есть немаленькое community, да и весь спектр бандлов Symfony для него родной. Он бесплатен в Community версии, исходники лежат на GitHub. Есть документация и поддержка через Stack Overflow.
    Ответ написан
    4 комментария
  • Как настроить обновления вебсайта на Wordpress?

    @Flying
    Есть такая штука как VersionPress, сам плагин бесплатен. Пользоваться не доводилось, но выглядит многообещающе. Также у Delicious Brains в блоге есть немало информации, в частности проскакивали статьи по деплою Wordpress сайтов. Точные ссылки сейчас не найду, но были, посмотрите.

    Для себя организовал этот процесс в виде плагина для Composer'а для того чтобы ставить Wordpress и плагины через него, так что деплой в целом не сильно отличается от других сайтов. Конечно есть своя специфика, но она зачастую весьма неплохо рулится за счёт wp-cli.
    Ответ написан
    1 комментарий
  • Как в браузере firefox сделать чтоб отображалась ширина и высота в пикселя при изменении размера окна?

    @Flying
    Предполагаю что имеется в виду ruler, он включается на тулбаре в Dev Tools, а если там нет - то в настройках:
    5ca4cfd62c001257601513.png
    Ответ написан
    1 комментарий
  • Как перейти с VS Code на PhpStorm?

    @Flying
    В первую очередь это, конечно, вопрос привычки, через недельку-другую попустит :) Я тоже плевался первое время когда с Eclipse переехал на него.

    В PHPStorm 2019.1 появилась возможность создавать полностью свои темы, так что в целом визуально вы можете сделать всё под себя, вопрос в трудозатратах на создание и поддержку. Если решитесь - не забывайте что продукт активно развивается и придётся не только сделать, но и в дальнейшем дорабатывать тему.
    Ответ написан
    Комментировать
  • Как зарабатывать 1000$ на фрилансе верстальщику?

    @Flying
    Работайте на более дорогих рынках, это позволит либо меньше работать либо больше зарабатывать. Для выхода туда в первую очередь необходимо знание английского языка, к сожалению вы не указали знаете ли вы его на достаточном уровне. Если нет - это прекрасная цель для инвестиции своего времени, если да - то странно что вы продолжаете работать там где за 2 недели можно заработать 15 тысяч рублей.

    Если вам удалось получить достойный рейтинг на одной бирже - то, хоть и не сразу, должно получиться и на другой. Кроме того не редкость когда единичный заказ перерастает в долгосрочное сотрудничество уже на других условиях.

    Позаботьтесь о том как ваша работа представлена в публичном пространстве. Профиль на GitHub где можно оценить вашу работу с кодом, профили на Stack Overflow и Тостере где можно оценить ваши вопросы / ответы и т.п. Портфолио ваших работ которое можно быстро показать чтобы представить вашу работу в выгодном свете - всё это даст вам возможность постепенно повышать ставку и иметь аргументы для её оправдания что, со временем, обязательно приведёт к росту доходов. Сейчас, насколько позволяет об этом судить быстрый поиск по вашему username в интернете, во всех этих областях дела не очень хорошо, поэтому вы не выделяетесь из общей массы исполнителей. А если ещё и соглашаетесь работать "за еду" - то именно так вас и будут оценивать.

    Естественно что самообучение и развитие в актуальных областях тоже являются необходимыми факторами. Также очень важна обратная связь, к примеру здесь нередко просят провести code review, а на Stack Overflow для этого есть даже отдельный раздел. Если бы у вас в профиле были ссылки на портфолио - можно было бы сделать какой-то вывод о вашем нынешнем уровне и его соответствии вашим ожиданиям по оплате.

    Мораль проста: развивайтесь и не продавайте своё время дёшево, тогда всё наладится :)
    Ответ написан
    1 комментарий
  • Почему не подключаются стили и иконки к сайту?

    @Flying
    Они подключаются, просто у вас стили в репозитории пустые, сами посмотрите. С SVG картинками ситуация чуть другая, такого файла просто нет в репозитории.

    В общем проверяйте что вы туда залили
    Ответ написан
    Комментировать
  • Дайте оценку верстке?

    @Flying
    Визуально выглядит вполне пристойно и очевидных косяков почти нет, но если копнуть глубже - возникают вопросы.

    Есть целый ряд претензий по использованию графики. Часть их них, безусловно относится к косякам дизайнера, но и вы отработали не самым лучшим образом.

    Из наиболее заметного - заглавная картинка с автомобилем в PNG которая занимает почти 600кб и из-за этого грузится весьма и весьма неспешно (и заметно для пользователя). В целом это по большей части косяк дизайнера, не приложившего усилий к тому чтобы выбрать правильную графику (автомобиль снят явно на улице и отражения в стёклах дают существенный вклад в визуальный шум и, как следствие, в размер картинки, нужно было выбирать фотографию сделанную в специальном помещении). Кроме того дизайнер, очевидно, не слышал про требования к такси в Нью-Йорке и рисовал как взбредёт в голову, но оставим это на его совести. Сочетание фоновой картинки, на которой весь траффик едет в обратном направлении и делает автомобиль такси нарушающим правила дорожного движения - тоже на совести дизайнера.

    Однако и в этом случае и, тем более, в случае фоновых изображений ниже по странице вы допускаете ошибки с выбором форматов файлов, способами их вставки в страницу и оптимизацией. К примеру из картинки с автомобилем можно выжать почти 100кб просто за счёт использования оптимизаторов. Гораздо грустнее ситуация с фоновыми картинками ниже по тексту. Во-первых вы сохраняете фотографии в PNG, получая на выходе файлы по мегабайту, хотя они же в JPEG занимали бы в 5-10 раз быстрее. Во-вторых вы, скорее всего, сохранили фоновые картинки уже обработанными (затемнёнными). Я не видел макета, но предположу что там эти картинки стоят в их оригинальном виде и на них наложены какие-нибудь фильтры. На первый взгляд кажется что проблемы нет, но на практике (в случае вёрстки для реального сайта) вы вынуждаете человека который будет поддерживать сайт либо готовить картинки с такой же пост-обработкой либо мириться с тем что стиль сайта меняется. Правильное решение здесь - грузить картинки как они есть и реализовывать фильтры на CSS, тем более что здесь это делается элементарно через multi background или псевдо-класс с полупрозрачным фоном. Очевидно также что для таких тёмных картинок вполне можно использовать JPEG с меньшим качеством и тем самым существенно сэкономить пользователям трафик.

    Ещё одна проблема связанная с фоновыми картинками - вы не подкладываете под них близкий по цвету solid color. Попробуйте включить в dev.tools "Network throttling", отключить кэш и перегрузить свою страницу - думаю вы поймёте что я имею в виду - белые блоки с белым текстом стоят довольно продолжительное время, постепенно заполняясь довольно тёмными картинками. Если бы background-color под ними был бы чёрным - проблемы бы не было.

    Далее - логотип. Обычно логотипы разрабатываются отдельно и даже если он выглядит просто набранным шрифтом - это вовсе не значит что это не так. Логотип Google, Microsoft или Яндекс - тоже просто название, но, надеюсь вы не сверстаете их, написав надпись текстом? В общем логотип = картинка, лучше в векторе. Сейчас даже одно съезжание слогана на пиксель влево относительно названия уже рушит всю конструкцию логотипа.

    Обратите внимание на то как вы работаете с формами. Все поля в форме являются <input type="text">, хотя часть названий явно намекает на date / time селекторы, а "Choose Vehicle" - на список выбора.

    Хотелось бы отметить работу с иконками - их всё-таки лучше хранить в SVG и либо требовать с дизайнера либо подбирать на том же Icon Finder. При этом оформление (те пресловутые жёлтые кружки) лучше делать через CSS т.к. это позволяет вам существенно гибче работать с размерами элементов.

    Есть всякие недочёты касающиеся responsive, к примеру, внимание как отображается блок "Our Tariffs" в размере чуть более 600px, в частности название тарифа и описание.

    Пожалуйста обратите внимание на то что вы используете два разных меню для desktop и mobile представления. В целом в вашем случае меню довольно простое и можно было бы обойтись одним. Конечно две копии используют часто, но у этого решения есть свои недостатки (в частности отсутствие синхронизации состояния), так что вы должны осознанно принимать решение по таким вопросам. Кроме того inline обработчики onclick там явно могут быть заменены на элементарный
    document.querySelectorAll('.menu a, .menu-hover a').addEventListener()
    что явно сделает код более простым и поддерживаемым.

    Ещё один важный момент который зачастую опускают при вёрстке - поведение макета с реальными данными. То что дизайнер в макете понапихал везде lorem ipsum и тексты примерно одинакового размера - отнюдь не означает что на реальном сайте эти условия будут соблюдаться. Отсутствие навыка проверять поведение макета в изменяющихся условиях ведёт к множеству ошибок которые не видны в условиях синтетических данных. К примеру попробуйте в блоке "We Do Best Than You Wish" (претензии по поводу английского языка оставим в стороне) в любом из элементов банально увеличить количество текста в 2-3 раза. В Chrome это приводит только к излому сетки, в Firefox - ещё и к изменению размера иконки. При этом я предполагаю что Firefox ведёт себя правильно т.к. пропорции элементов изменились, а ограничения размеров на картинки у вас не заданы.

    В целом похоже что макет верстался и проверялся только в Chrome. К примеру посмотрите как ведёт себя картинка с рукой и телефоном в Firefox при изменении размеров. Опять же Firefox вполне корректен т.к. вы не обрезали картинку корректно, предпочитая выгрузить "как есть" и подгонять положение в CSS, но забыв при этом про overflow: hidden для контейнера.

    Теперь перейдём к CSS:

    Обратите внимание на то как вы подключаете внешний шрифт:
    family=Lato:400,700,700i,900,900i&amp;subset=latin-ext
    . Возникают два вопроса:
    1. Зачем вам subset=latin-ext на сайте где есть только базовая латиница?
    2. Как вы выбирали начертания? У вас подключаются 5 начертаний (400, 700, 900 + два italic'а), при этом grep по CSS даёт значения font-weight 200, 300, 400, 500, 600, 800 и ни одного italic. Вам не кажется что эти множества почти не пересекаются?


    Кроме того вы постоянно забываете про fallback шрифты что на медленном интернете и при отсутствии инструкций для font loading приводит к невидимому контенту страницы на период загрузки.

    Отсутсвие ограничения по ширине для .wrapper приведёт к недопустимо широкому сайту на больших мониторах с высоким разрешением. Можете уменьшить масштаб страницы до 50% и полюбоваться результатом.

    В стилях повсеместно используются достаточно общие названия классов в global namespace. К примеру кто бы мог подумать что стилизует селектор .text? Вы уверены что нигде больше на сайте подобный селектор не встретится? Даже при дальнейшем развитии сайта? Другими словами именование селекторов - важная часть работы, вы можете использовать любую методологию (тот же БЭМ или что-то ещё) или разработать свою, но ваш код не должен ломаться при добавлении ещё пары блоков, особенно если это будет делать другой человек.

    Списки элементов, к примеру тот же .product-cont лучше делать именно списками, а не распихивать элементы по столбцам вручную, благо flexbox и column layout здесь всё прекрасно сделают за вас, зато имея одноранговый список вы обеспечите себе куда большую свободу действий.

    Использование id в качестве CSS селектора - плохая практика, но у вас таких мест немало, 11 штук.

    Уверен что мог бы найти ещё что-то, но надеюсь для затравки хватит, и так много получилось... :)
    Ответ написан
    4 комментария