Ответы пользователя по тегу Symfony
  • Почему не правильно работает расширение twig?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    $twig->addFunction(new Twig_SimpleTest(...));
    В ошибке написано - нужно создать объект, реализующий интерфейс Twig_FunctionInterface или объект Twig_SimpleFunction. А вы передали объект класса Twig_SimpleTest().
    Может, у вас синтаксическая ошибка? Twig_SimpleTest -> Twig_SimpleFunction
    Ответ написан
    2 комментария
  • Как с помощью rabbitmq ускорить отправку писем (php)?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    сам по себе никак. rabbitmq, zeromq, gearman и подобные не выполняют задачи, вы должны сами делать обработчик, который будет обрабатывать. А подобные очереди делают очень простую вещь - дают программе быстро передать задачу в очередь так, чтобы обработчик (обработчики) мог заниматься делом.
    Ответ написан
    3 комментария
  • Почему Datepicker в Symfony 2 сохраняет выбранную дату со сдвигом на 1 день?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Эти известная бага https://github.com/symfony/symfony/issues/12808
    Почитайте, там есть грязный workaround. Чем закончилось - уже не помню.
    Ответ написан
  • Веб приложение на Symfony Components, как правильно?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    1) По поводу моделей.
    Symfony не пропагандирует MVC и слоя такого как модель нет

    На самом деле, Symfony хотя и не пропагандирует MVC (потому что есть MVVM, например), но легко может использоваться с MVC, всё для этого в ней есть. Единственно чего нет в Symfony - нет готового решения моделей. Почему - потому как разные ОРМы будут использовать разные решения. Но я рекомендую использовать Доктрину, в ней вообще не нужно думать о сложных моделях - просто делайте plain-php класс для объекта, без специальных базовых классов для модели.
    class Person {
        public $firstname;
        public $lastname;
    }

    и этого достаточно. А доктрина умеет взять это и создать таблицу базу данных, получать оттуда в список записей, создавать новые и пр. Лучше, конечно, в классе поля сделать приватными, сделать геттеры/сеттеры, возможно - добавить методы бизнес-логики. Многие любят прямо в классе модели указывать метаданные полей (тип данных в БД) с помощью аннотаций, а некоторые переносят в отдельный yml-файл.

    В общем, раз хотите учиться - берите Doctrine2. Возможно, он работает медленнее, но зато даёт очень удобное создание моделей.

    2) По поводу шаблонизатора. Берите Twig. Он прекрасен. Удобно создавать свои функции, легко наследовать и переопределять блоки.

    3) Валидацию моделей можно делать двумя способами - валидировать формы или валидировать модель. Начните с валидации форм, в симфонии это делается достаточно легко.

    4) Авторизацию с аутентификацией тоже можно использовать симфониевскую - компонент Security.

    5) Не забудьте взять компоненты DependencyInjection, Config, OptionsResolver, Yaml. Подумайте ещё о Routing, Translation, Debug, EventDispatcher, Intl и Validator. И тогда у вас получится Symfony Framework :)
    Ответ написан
    5 комментариев
  • Как правильнее реализовать получение данных со стороннего API?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    >Как правильнее обращаться к сторонниму API
    Лучше всего, сделать сервис, в котором будет ваш код связи с-чем-угодно. А в самом приложении использовать сервис, как высокоуровневый элемент. Если вы видите, что этот код может в будущем будет использоваться в разных проектах, то тогда есть смысл вынести в отдельный бандл. Я не вижу большого смысла разделять один проект на разные бандлы (разве что специально сделать их очень слабо связанными).
    Почитайте мой ответ в другом вопросе.

    >как дополнять либы новым функционалом?
    Форкнуть либу, дополнить вашим кодом, и подключать ваш форк. Это общее правило, не только для Symfony, и не только composer. Иначе, если автор библиотеки выпустит новую версию (новую функцию или исправление бага), то ваше изменение будет конфликтовать с новой версией либы.
    Ответ написан
    Комментировать
  • Можно ли использовать switch внутри for в twig?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Twig не поддерживает тег {% switch %}. Используйте if/elseif вместо него.
    Ответ написан
    5 комментариев
  • Форма и валидация со стороннего сервиса. Как правильно поступить?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Форма создаётся в первом бандле, но (в данном случае) не используется, а используется во втором бандле? То есть, форма использует Request в контроллере во втором бандле?

    Сделайте форму отдельным сервисом, не используйте создание формы через билдер в контроллере. Это, кстати, вообще удобнее - сначала создать форму, а в контроллере создать её через $form = $this->createForm('my_form');
    Ответ написан
  • Как в Symfony 2 раскодить ( decode ) захешированный пароль ( password_hash() )?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Никак. В том и смысл хэша, что из него невозможно получить изначальный пароль.
    Вам даже брутфорс не поможет, если у вас длина пароля больше 3-5 символов.

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

    А если пароль нужен позже (например, для функции восстановления пароля), то так не получится - пароль нужно пересоздавать заново.
    Ответ написан
    Комментировать
  • Как проверять данные при использовании RESTFul api в Symfony2?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Можно сделать фейковые формы, и использовать в них стандартные валидаторы. А можно делать другим способом, более интересным - использовать OptionsResolver - да-да, те самые, которые в формах используются.
    Ответ написан
    Комментировать
  • Подходит ли framework Symfony?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Мне кажется, что если у вас есть такие вопросы, то вам рано браться за такие проекты.

    А по существу вопроса - берите любой трендовый фреймворк, и не ошибётесь. Берите Symfony2, Zend Framework 2, Yii2, Laravel, Phalcon. Они сопоставимы, разным людям нравятся разные фреймворки.

    Лично мой выбор - Symfony2. Он с лёгкостью подойдёт для вашей задачи. Но чем сложнее задача, тем меньше важен будет конкретный фреймворк.

    Symfony требует хорошего знания ООП вообще и php в частности. Другие фреймворки тоже требуют, но симфония особенно.
    Ответ написан
    Комментировать
  • Как добавить существующую сущность в выпадающий список (иконка "+") в SonataAdminBundle?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Этот список называется add_block. Сам по себе он вроде нигде не прописан, нужно создавать его самостоятельно. На самом деле, я это делал год назад, сейчас работа с этим списком может быть упрощена. Я делал это так (я изменял сонатовский список сущностей, чтобы там выглядело как мне нужно было):
    {# app\Resources\SonataAdminBundle\views\Core\add_block.html.twig #}
    {% block add_block %}
        {% set items_per_column = admin_pool.getOption('dropdown_number_groups_per_colums') %}
        {% set groups = [] %}
    
        {% for group in admin_pool.dashboardgroups %}
            {% set display_group = false %}
    
            {% for admin in group.items if display_group == false %}
                {% if admin.hasRoute('create') and admin.isGranted('CREATE') %}
                    {% set display_group = true %}
                    {% set groups = [group]|merge(groups) %}
                {% endif %}
            {% endfor %}
        {% endfor %}
    
        {% set column_count = (groups|length / items_per_column)|round(0, 'ceil') %}
    
        <div class="dropdown-menu multi-column dropdown-add"
            {% if column_count > 1 %}style="width: {{ column_count*140 }}px;"{% endif %}
                >
            {% for group in groups|reverse %}
                {% set display = (group.roles is empty and is_granted('ROLE_SONATA_ADMIN') ) %}
                {% for role in group.roles if not display %}
                    {% set display = is_granted(role) %}
                {% endfor %}
    
                {% if display %}
    
                    {% if loop.first or loop.index0 % items_per_column == 0 %}
                        {% if loop.first %}
                            <div class="container-fluid">
                                <div class="row">
                        {% else %}
                            </ul>
                        {% endif %}
    
                        <ul class="dropdown-menu{% if column_count > 1 %} col-md-{{ (12/column_count)|round }}{% endif %}">
                    {% endif %}
    
                    {% if loop.index0 % items_per_column != 0 %}
                        <li role="presentation" class="divider"></li>
                    {% endif %}
                    <li role="presentation" class="dropdown-header">{{ group.label|trans({}, group.label_catalogue) }}</li>
    
                    {% for admin in group.items %}
                        {% if admin.hasRoute('create') and admin.isGranted('CREATE') %}
                            <li role="presentation">
                                <a role="menuitem" tabindex="-1" href="{{ admin.generateUrl('create')}}">{{ admin.label|trans({}, admin.translationdomain) }}</a>
                            </li>
                        {% endif %}
                    {% endfor %}
    
                    {% if loop.last %}
                                </ul>
                            </div>
                        </div>
                    {% endif %}
    
                {% endif %}
            {% endfor %}
        </div>
    {% endblock %}


    Там же лежит user_block (который я чаще использую в проектах, чем add_block):
    {# app\Resources\SonataAdminBundle\views\Core\user_block.html.twig #}
    {% block user_block %}
    <li><a href="#"><strong>{{ app.user.name }}</strong></a></li>
    <li><a href="{{ path('fos_user_change_password') }}">Сменить пароль</a></li>
    <li><a href="{{ path('fos_user_security_logout') }}">Выйти</a></li>
    {% endblock %}
    Ответ написан
    2 комментария
  • Symfony2 формы Как вызвать валидатор раньше трансформера?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Дело в том, что валидация проверяется при обратной трансформации, поэтому, всегда вначале происходит трансформация, а потом только - валидация.

    Вы должны делать валидацию не через стандартные Constraints, напишите свою проверку, и запускайте её через событие, использующее FormEvents::PRE_SUBMIT.

    В этом ответе есть об этом чуть больше инфы.
    Ответ написан
    1 комментарий
  • Почему symfony2 при чистке кеша лезет в базу?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    При запуске консольной команды запускается ядро (kernel), который парсит параметры из config.yml и инициализирует бандлы. Бандл доктрины при этом присоединяется к БД. Можно ли что-то с этим сделать, я не знаю.
    Может, выходом будет сделать свой собственный уровень окружения (environment), в котором не добавлять бандл доктрины, и запускать это окружение при вызове консольной команды.
    Ответ написан
    Комментировать
  • Есть ли в symfony2 бандлы-аналоги Yii2 GridView (см скриншот)?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Я для сложных таблиц использую jquery-плагин DataTables, мощный плагин с множеством функций. Причём я использую его напрямую, без бандлов (я пока не использовал так много его функций), но есть бандлы, которые включают поддержку DataTables в проект на symfony.
    https://github.com/stwe/DatatablesBundle
    https://github.com/AliHichem/AliDatatableBundle
    Я их не использовал, но на вид они интересные.
    Ответ написан
    Комментировать
  • Как реализовать, закрыть сайт на время в symfony?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Есть статья, описывающая, как делать Maintenance mode на сайте. С готовыми кодами.

    И есть бандл LexikMaintenanceBundle, который делает это.
    Ответ написан
  • Как сохранить изображение в Symfony при использовании 2ух бандлов?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Я бы хранил кропленные картинки прямо бандлом ComurImageBundle, без iPHP. ComurImageBundle сам сохранит оригинальный файл (если надо, можно выключить) и обрезанный файл в указанную папку, причём сохранит сам через ajax, ещё до сохранения формы, и в сонату придёт уже готовая строка с уже готовым файлом (обрезанным и оригинальным).
    Убирайте из полей сущности атрибуты, связанные с iPHP и делайте их string вместо array. То есть, делайте прямо как описано в документации бандла ComurImageBundle. А если вам ещё нужно что-то делать ещё и с iPHP, то дополнительно делайте новые поля для iPHP, и сами вручную сохраняйте нужные данные для них в prePersist, как вам советует Денис
    Ответ написан
    Комментировать
  • Как в Twig вывести вывод метода класса?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Запустить статический метод класса можно вызовом через объект этого класса:
    class Test {
        private $x = 10;
    
        public static function getSTatic() {
            return 'static';
        }
        public function getNormal() {
            return 'normal ' . $this->x;
        }
    }

    Теперь в контроллере нужно создать объект этого класса и передать в шаблон:
    {{ test.normal }}
    {{ test.static }}

    В вашем случае можно вызвать вот так: {{ city.nameFromId(salonTables.cityId)) }}, где city - объект класса City.

    Но вообще-то у вас лучше переделать всё полностью. Судя по тегу Symfony в вопросе, вы пользуетесь фреймворком Symfony2. Тогда вам вообще не стоит писать статические методы для получения записей, воспользуйтесь доктриной.
    1) В шаблоне неправильно обращаться к базе данных, правильно подготовить все нужные данные в контроллере и передать их в шаблон:
    class SalonController extends Controller
    {
        /**
         * @Route("/salon/{id}")
         * @Template
         */
        public function salonAction($id)
        {
            $salons = $this->getDoctrine()->getRepository('AppBundle:City')->findBy(array('cityId' => $id));
    
            return array('salons' => $salons);
        }
    }

    2) твиг сам экранирует вывод, делать |escape не обязательно
    3) не стоит добавлять слово table в имя сущности, гораздо лучше писать их вот так:
    {% for salon in salons %}
    { salon.name }}
    {{ salon.cityId }}
    {% endfor %}
    Ответ написан
    Комментировать
  • Symfony 2. Как вывести в форме value selected в списке внедренной формы?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Похоже, проблема в том, что при создании формы создаётся и новый объект статуса, который не имеет установленного статуса:
    $builder->add( 'status', new formStatusType() )

    Попробуйте передать объект статуса в форму:
    class formEditOldemandType extends AbstractType
    {
        public function buildForm( FormBuilderInterface $builder, array $options )
        {
            $builder->add( 'status', $options['status'] )
            ...
        }
    
        public function getDefaultOptions(array $options)
        {
            return array(
                'data_class' => 'Acme\AppBundle\Entity\Oldemand',
                'status' => new formStatusType(),
            );
        }
    
        public function getName()
        {
            return 'formcloseoldemand';
        }
    }


    У вас старая версия Symfony - метод getDefaultOptions() убран в версии 2.3, и уже в версии 2.1 вместо него используется метод setDefaultOptions(), а в версии 2.7 используется configureOptions(). Вам следовало бы указать этот факт в вопросе. Какая версия использована в вашем проекте?
    Ответ написан
  • Как изменить параметр в Symfony2?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    А где вы пытаетесь установить параметр? и нужно устанавливать в конфигураторе бандла - в классе DependencyInjection\YourBundleExtension. После этого контейнер замораживается, и его изменить нельзя. Если вам это нужно - значит, вы что-то неправильно делаете в архитектуре.
    Если вам нужно изменить параметр на уровне разработки - ставьте нужное значение в parameters.yml (замените Анадырь на Канчалан). А если нужное значение определяется в коде, то его не нужно устанавливать в параметр контейнера, его нужно передавать через аргументы метода сервиса.

    Расскажите подробнее, что у вас за задача, чтобы можно было подробнее подсказать.
    Ответ написан