Друзья, а поделитесь опытом, как именно вы поступаете в таких ситуациях...

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

Варианта два.
1. Переопределить сервис и в нужной части сделать изменения, чтобы работало корректно.
2. Сделать изменения и создать PullRequest на GitHub.

Если по первому варианту вопросов нет, то по второму есть.

Есть у кого то опыт работы с проектом на Symfony  и в то же время менять бандл вендора в дальнейшем делая pullrequest ?
Ведь если просто стянуть форк сделать там изменения то как его проверять в рамках проекта ?

Я вижу два пути.
Путь первый - Делаем форк, добавляем в composer.json

 "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/younickname/BundleName"
    }
  ],

в списке пакетов  меняем ветку соответствующего бандла на "dev-master" например или на "dev-brahcn_name"
Делаем изменения, пушим изменения, делаем composer update venodr/bundle   
И так по любому изменению.

В общем не очень верный путь, как по мне.


Путь второй. Клонировать свой форк непосредственно в папку с вендорами. Тогда в рамках одного проекта можем делать изменения любые, потом когда все работает - делаем пуш и пул реквест вендору и ждем что его примут.  (кто пользует тут ide предполагаю что нужно чутка знания консоли чтоб работать с git , но кто занимается такими вещами, думаю знает).

Ну и естественно что есть еще какой то вариант, а именно  правильный вариант.  Вот его я ищу. Как делаете вы ?

2

(3 ответов, оставленных в Изучение Symfony)

Спасибо, читал в мануале о наследовании, собственно уже одно наследование реализовано, множественное наследование я предполагаю невозможно сделать, по сему буду как то пока выходить из ситуации как могу (писать лишний код default/smile ), а там дальше буду уже разбираться с этим из мануала , благодарю очередной раз за направление default/smile)

О чем я.
Предположим существуют сущности

Event, Storage

.
В каждой из сущностей помимо своих полей существуют поля одинаковые. Пусть это будут поля

src
link
active

Предположим что существует сущность

Banner

имеющая поля

src
link
active

Вопрос - как мне связать (и возможно ли это) сущности, чтоб в зависимости от выбранного мною типа я получал после запроса коллекцию сущностей

Banner

имеющие данные пересекающихся полей (в нашем случае src link active) других сущностей, связанных с Banner.

Т.е. к примеру у меня есть TwigExtenstion

public function render_banner($type)
    {
...
 
    }

Его задача взависимости от передаваемого типа рендерить баннер. Соответственно тип будет указывать из какой сущности мне этот баннер забирать. Я могу сделать ка кто например так -

public function render_banner($type)
    {
        $em = $this->getService('doctrine.orm.entity_manager');
        $bannerFactory = new BannerFactory();
 
        $item= $bannerFactory->createItem($type);
        $result = $item->getResult($em);
        $templating = $this->getService('templating');
        $render = $templating->render('@VplanningPage/Elements/banner.html.twig', array('banners'=>$result));
        return $render;
 
    }

Но понятно что тут мне приходится для каждого типа создавать класс обслуживающий соответствующую сущность и отдающую мне нужные мне картинки, я же хочу получить  ответ непосредственно из Doctrine причем в ответе получить совершенно определенный тип сущности Banner, данные в котором получаю из других сущностей, поля которых пересекаются ну и которые возможно связаны с Banner один к одному.

Думал еще над тем, что возможно мне надобно сущности типа Event и Storage наследовать от Banner, но ничего дальше придумать пока не смог.

4

(1 ответов, оставленных в Symfony 2.6–2.8)

Вышел релиз 2.7, при обновлении получаю кучу варнингов  о deprecated функциях. Насколько я понимаю все варнинги должны фиксить разработчики бандлов. Вопрос не нов - что делать ? Попросту подождать ? Как быть с бандлами который разработчики перестали поддерживать ? Форкать ? Так нет знаний для этого достаточных, либо попросту пока повременить с 2.7 и существовать себе спокойной с 2.6 ? Кажется более здравой мыслью. Работает- не лезь default/smile

5

(4 ответов, оставленных в Изучение Symfony)

Спасибо всем за разъяснения.  Единственное неудобство возникает в случае если выйдет обновление библиотеки. Благо данная библиотека реализована в одном единственном классе, который я попросту скопировал и отредактировал, включив варнинг, но в итоге на сколько я понял, такая ситуация вылазит только в dev режиме, по сему особо проблем в итоге нет. Спасибо.

6

(4 ответов, оставленных в Изучение Symfony)

Конекта нет в любом случае, т.к. я mpd (это демон, который крутит музыку) тушу предварительно. Моя задача проверить "живые" демоны. Проверить я их могу приконектившись к ним или нет. В моем случае сервер демона выдает Connection refused, по понятным причинам, и я справедливо предполагаю что соект не должен создаться.  Вот это

if(!static::$fp)
  {
   // no connection
   throw new MPDConnectionFailedException("$errstr ($errno)");
  }

и есть проверка сокета на жисть , насколько я понимаю я должен именно это исключение получить,оно должно быть выброшено. Но получаю в итоге  Warning. Значит сокет не зависимо от того открыт или нет - существует ?  Не понятен тогда смысл в коде выброса исключения, которое я жду.

Хотя возможно стоит другими методами проверять открыт ли порт ?   Что то типа telnet в варианте php , хотя я почему то как то считал что telnet это и есть открытие сокета в варианте php

update:
Помогло выключение варнинга с помощью @. Не уверен что это лучший вариант, но возможно единственный ?

7

(4 ответов, оставленных в Изучение Symfony)

Скорее всего это не относится к symfony, но не задать вопрос я не могу, т.к. ума не приложу что делаю не верно, хотя это то что не должно вызывать вопросов. Так или иначе, как обычно, мне не очень стыдно показать свою неграмотность default/smile

Ближе к делу. 

В трех словах - есть php класс который умеет управлять mpd демоном. Все хорошо, кроме того что если демон не запущен, то при попытке подключения выдает 500ую ошибку

 Warning: fsockopen(): unable to connect to planeset.ru:6600 (Connection refused)
500 Internal Server Error - ContextErrorException 

хотя в коде есть   

if(!static::$fp)
  {
   // no connection
   throw new MPDConnectionFailedException("$errstr ($errno)");
  }

я пишу

try {
            MPD::connect($source->getMpdpassword(), $source->getMpdhost(), $source->getMpdport());
        } catch (MPDConnectionFailedException $e) {
            return false;
        }

Но хоть убей, не перехватывает это исключение

Как мне быть в этом случае ? Куда копать, чтоб не крашилось все ?

8

(19 ответов, оставленных в Изучение Symfony)

Поехало и после выхода релиза доктрины 2.5 приехало default/smile)

CRITICAL - Uncaught PHP Exception Doctrine\ORM\Query\QueryException: "[Semantical Error] line 0, col 308 near 'city2 IS NOT': Error: Cannot add having condition on a non result variable." at ..../vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php line 63

Пока исключение мне ничего не говорит, сколько бы я его не читал. Поехал копать default/smile

В анонсах к версии 2.7 увидел вот такое - http://symfony.com/blog/new-in-symfony- … provements

Еще не понял чем это грозит, но не решение ли это проблемы десиарилизации ?

10

(19 ответов, оставленных в Изучение Symfony)

Все поехало!  Как раз по первому варианту! Был невнимателен почему-то. Убил сегодня целый день, хотя ответ был у меня еще в прошлую пятницу. Спасибище! Пошел курить как же оно работает. Убил целый день, пока дошло что первый Ваш ваниарт я не использовал, взялся за второй. Мде...  default/smile

Вообще говоря этот запрос ровно тот, который мне нужен был, но я не мог его правильно составить, по сему у меня везде пока существут проверка "на область", здесь же я могу оперировать одним запросом, это просто замечательно. К сожалению я до сих пор не могу сообразить как он составлен default/smile Забрал SQL и через SQL редактор эксперементирую. Надеюсь дойдет это хитросплетение!  daemon_master, мой Вам огромный спасиб!

p.s. По второму варианту - там в SQL после джоина была такая контсрукция

JOIN xxx ON xxx.x = yyy.y AND (xxx.x=yyy.y OR zzzz.z = kkkk.k), т.у. OR присутствовал , но только после AND, в моем случае мне нужна была конструкция  ON (   OR    )  , ну да первый вариант запроса решил все мои проблемы.

Если б вы еще переводили со своего профессионального на мой, любительский... default/smile

Если линкуемый объект уже существует, то нет надобности его создавать/фетчить, чтобы прилинковать к создаваемому. Создавайте референсы и линкуйте их.

Я как всегда откровенен - для меня это что то очень новое, я не очень имею понятие о чем вы говорите, но чую - это очень важно и гугл мне в помощь, а Вам, как обычно - огромное спасибо!  Буду рыть default/smile

13

(19 ответов, оставленных в Изучение Symfony)

Не первый ни второй вариант не дает результата, выдавая ошибки, но в любом случае это уже что то, что можно будет покрутить, я попросту даже понятия не имел до этого момента что есть в билдере некие expr методы, почитаю, попытаюсь разобраться что к чему. Спасибо !

Ситуация мне кажется вполне интересная, хотя думаю мне надобно пойти чуть другим путем. В любом случае пришлось мне таки изобретать импорт в БД данных из экселя. И вроде бы ничего нет сложного, возьмем PHPEXCEL и парсим как надо , занося данные в сущности, вот только одно НО...

Есть некий список, в нем есть адреса и должны быть координаты взятые из ymaps. Все бы хорошо, но геокодирование я могу производить только через js. В итоге я прихожу к такой схеме, что парсю файл, создавая массив сущностей, имеющих между тем отношения многие к одному. Отдаю в шаблон json через json_encode, реализуя в сущностях интерфейс JsonSerializable, потом уже в шаблоне подгружается ymaps , осуществляю геокодирование , вставляю нужные результаты туда куда нужно и аяксом шлю дальше - на вставку в БД. И вот тут начинаются сложности.

Принимаю я JSON, и при json_decode я естественно получаю не нужные мне классы, а stdClass . И все бы ничего, если бы не было зависимостей , которые мне обязательно нужно вставлять в базу. Я бы создал нужный объект, закинул бы туда нужные данные и все, а тут приходится еще создавать классы дополнительно чтоб реализовать все отношения. И тут вроде бы можно тупо встречая эти ключи создавать класс и заполнять нужными данными, но чую я это не тот подход который можно назвать правильным ибо любой чих или любое изменение приведет к череде пересмотра кода...

Хотя что то подсказывает мне что вернее будет сформировать форму, но пока не вижу правильного пути как в эту форму вставить нужные мне данные из yandex geocoder, возможно как то через eventы или transform , хожу вокруг, но мысль правильную за хвост поймать не могу. Возможно кто то сможет подсказать ? Если конечно я не слишком запутанно объяснил. Спасибо.

15

(19 ответов, оставленных в Изучение Symfony)

daemon_master пишет:

OR в Join QueryBuilder-а, хз как вставить.

Но можно запрос перепилить, и тогда можно засунуть в QueryBuilder. Но чет он как-то извращенно смотрится, ИМХО
SELECT c1.*, c2.*, COALESCE(s1.city_id, s2.city_id) AS city_id FROM TABLE.cities AS c1
LEFT JOIN TABLE.cities AS c2
ON (c1.id = c2.area_id)
LEFT JOIN TABLE.storages AS s1
ON s1.city_id = c2.id
LEFT JOIN TABLE.storages AS s2
ON s2.city_id = c1.id
WHERE c1.id = ... мои параметры ... AND ((s1.city_id IS NULL AND s2.city_id IS NOT NULL) OR (s1.city_id IS NOT NULL AND s2.city_id IS NULL));

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

Ветка эта тут - http://stackoverflow.com/questions/2923 … erybuilder  .

В общем и целом на мой работающий сейчас запрос

$query = $em->getRepository('VplanningPageBundle:Storage')
            ->createQueryBuilder('s')
            ->innerJoin('s.city', 'c1')
            ->innerJoin('c1.area', 'c2')
            ->innerJoin('s.storagestype', 'st')
            ->where('c2.id = :cityID')
            ->andWhere('st.typename = :storagesTypeName')
            ->andWhere('s.active = :active')
            ->setParameters(array(
                'cityID' => $cityID,
                'storagesTypeName' => $storagesTypeName,
                'active' => 1
            ))
            ->orderBy('s.adress')
            ->getQuery();

куда мне и нужно включить ON (..OR..) написали такую интересную штуку

$qb->join('storage.city', 'city', Join::WITH)
   ->join('city.area', 'area', Join::WITH, $qb->expr()->eq('area.id', ':cityID'))
   ->join('storage.storagestype', 'type', Join::WITH, $qb->expr()->eq('type.typename', ':storagesTypeName'))
   ->where('storage.active = :active')
   ->setParameters(array(
       'cityID' => $cityID,
       'storagesTypeName' => $storagesTypeName,
       'active' => 1
   ))
   ->orderBy('storage.adress');

Вот уж я даже не представляю о чем речь, т.к. я не настолько глубок в Doctrine, но может кого более опытного натолкнет на мысли  ? default/smile

16

(19 ответов, оставленных в Изучение Symfony)

Ответа так и не нашел, может кто то в курсе дела ? default/smile

17

(20 ответов, оставленных в Изучение Symfony)

->select('u.feature_id');

Думается мне такая конструкция не катит.  У меня есть похожая история, выборка в которой происходит через анонимную функцию.

$form = $this->createFormBuilder()
            ->add('cities', 'entity', array(
                'label' => 'Выбрать город :',
                'class' => 'Site\YMapsBundle\Entity\City',
                'property' => 'name',
            'query_builder' => function (EntityRepository $er) use ($doohtype) {
                  return $er->createQueryBuilder('c')
                      ->join('c.storages','s')
                      ->join('s.storagetype','t')
                      ->where('t.typename =:storagetype')
                      ->andWhere('s.active = :active')
                      ->orWhere('c.id = :areaid')
                      ->setParameter('storagetype',$doohtype)
                      ->setParameter('active', '1')
                      ->setParameter('areaid', '109')
                      ->addOrderBy('c.prior', 'ASC')
                      ->addOrderBy('c.name', 'ASC');
    }
            ))
            ->getForm();

Может вам чем-то поможет.

18

(19 ответов, оставленных в Изучение Symfony)

Дабы не плодить темы, есть такой SQL запрос

SELECT * FROM TABLE.cities AS c1
LEFT JOIN TABLE.cities AS c2
ON (c1.id = c2.area_id)
INNER JOIN TABLE.storages AS s
ON (s.city_id = c2.id OR s.city_id = c1.id)
WHERE c1.id = ... мои параметры ...;

Подскажите если найдете нужным ответить, как мне конкретно вот это реализовать в QueryBuilder ?

ON (s.city_id = c2.id OR s.city_id = c1.id)

еще конеретней - OR

В трех словах  - исторически сложилось что Области живут в той же таблице что и города, по сему делаю SELF JOIN в моем случае LEFT JOIN чтоб получить города не имеющих областей и получить города, живущие в области.

И бъюсь, никак не пойму как реализовать нужный мне запрос в DQL.

Пока что сделал попросту проверку на область, но в этом случае строю два запроса.

Одно тянет за собой другое, потом третье... простите за мою назойливость, но к своему сожалению у меня не хватает еще базовых знаний, чтоб понимать множество очевидных казалось бы вещей. Ближе к делу, пожалуйста объясните мне русским языком, если такое возможно,

In any form, the three different types of data are:

    Model data - This is the data in the format used in your application (e.g. an Issue object). If you call Form::getData or Form::setData, you're dealing with the "model" data.
    Norm Data - This is a normalized version of your data, and is commonly the same as your "model" data (though not in our example). It's not commonly used directly.
    View Data - This is the format that's used to fill in the form fields themselves. It's also the format in which the user will submit the data. When you call Form::submit($data), the $data is in the "view" data format.

The two different types of transformers help convert to and from each of these types of data:

Я так понимаю это важно, но хоть тресни не пойму о чем идет речь и зачем это описано в мануале.  Т.е. я понимаю что есть представление в виде объекта, а есть  View представление, что по всей видимости является тем, как именно в DOM описываются элементы формы. В общем стражду в понимании, а понять не могу. Спасибо!

Спасибо большое, еще не добрался до раздела с компонентами, хотя иногда туда заглядывал с опаской.

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

Мне кажется их достаточно добавлять и удалять, но нам, к сожалению, такое потребовалось.

Мне действительно достаточно удалять и добавлять. Вся сложность заключается в том, что у меня существует цепочка collection типов.

City->storages->images

В каждом city  - collection storages в каждом storages - collection images. Все работает хорошо при добавлении новых storages , срабатывает prePersist которая отсылает к методу в storage ну и т.д., а вот при редактировании начинаются проблемы. Если я изменяю что либо в storage, что описано  в orm, то в общем то все хорошо, а вот если я изменяю лишь только атачи (добавляю), тогда у меня и случается затык, т.е. мне либо описывать все в контроллере, что я считаю не правильным в данном случае, либо вот то, что вы подсказали и что я как раз сел внимательно изучать.
Спасибо не устаю говорить, вы очень помогаете новичкам!

А подскажи-те ка, уважаемые, есть ли возможность вызвать принудительно событие в doctrine методом в сущности ?
Подробнее я вот о чем -
У меня есть сущность, описаны в orm свйоства все, кроме свойства files, куда у меня загружаются файлы. При создании нового объекта, прекрасно срабатывают prePersist и прочие соответствующие дела, которые в свою очередь вызывают метод в сущности, выполняющий требуемую задачу, но вот если я обновляю данные при этом изменяя только files, по понятным причинам эвенты не срабатывают, т.к. doctrine изменений собственно говоря не видит. Вот и вопрос возник, как мне при изменении свойства, не описаного в orm вызывать нужные мне события.

Спасибо!

23

(19 ответов, оставленных в Изучение Symfony)

daemon_master пишет:

to zalex

Когда ты вызываешь
createQueryBuilder('c')
внутри это происходит примерно так
$this->_em->createQueryBuilder()
            ->select($alias)
            ->from($this->_entityName, $alias);
Чтобы он начал выбирать и s, нужно всего лишь добавить еще одну секцию select
->addSelect('s')

Да да, я разобрался , просто с ходу решил с перепугу добавить Select, но через запятую в аргументах , а не методом, что логично. Вам же очередное спасибо, вы помогли уж как второй раз! Очень отрадно что у Вас есть на это время. Благодарю!

24

(19 ответов, оставленных в Изучение Symfony)

Кто бы сомневался, что вы окажетесь правы! default/smile И еще раз спасибо за посыл.
То, что я хотел делается  так

$query = $this->getEntityManager()->createQuery(
            'SELECT c,s FROM SiteYMapsBundle:City c
            JOIN c.storages s
            JOIN s.storagetype st
            WHERE c.id = :id
            AND st.typename = :storagetypename'

        )
            ->setParameter('id', $id)
            ->setParameter('storagetypename', $storagetype);

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

Боюсь правда в данной истории Symfony в чистом виде совсем не причем и данная тема не более как закрытие дырищ в моем невежестве в плане обязательных вещей. Благодарю за терпение еще раз.

25

(19 ответов, оставленных в Изучение Symfony)

Ну, и как полагается, мои бараны меня не отпускают, по сему приходится к ним возвращаться. Уважаемый daemon_master ткнул меня в правильном направлении, указав что нужно использовать join для выборки, а не собирать конструктор из нескольких запросов, но вот у меня опять случилось страшное - не выходит каменный цветок, а именно :

До сих пор у меня вот такая связь

city <- manyToOne <- storages -> manyToOne -> storagetype

Есть уже готовые шаблоны для вывода city, к нему нужно прикрутить в зависимости от storagetype собственно говоря эти самые storages. Думал решить задачу подобной выборкой -  где с - city
       

$query = $this->createQueryBuilder('c')
            ->innerJoin('c.storages', 's')
            ->innerJoin('s.storagetype','st')
            ->where('c.id = :cityid')
            ->andWhere('st.typename = :storagetypename')
            ->setParameter('cityid', $id)
            ->setParameter('storagetypename', $storagetype)
            ->getQuery();
        return $query->getSingleResult();

Я получаю то что ожидал на выходе - Объект City, но я ведь почему-то ожидал что свойство storages у City(который является ArrayCollection) заполнится значениями s (storages), которые в свою очередь пересекаются с storagetype, но в итоге я получаю сущность city со всеми Объектами  Storage, не зависимо от storagetype. Посмотрел в симфони - он показывает что делается дополнительный запрос на получение всех соответствующих city - storages.

Вопрос то собственно говоря вот в чем, как мне получить на выходе что я ожидал и как правильно это сделать? Могу предположить что можно (нужно) искать именно storages , тогда получу что нужно, но как все-таки мне получить требуемый результат именно в такой последовательности  ибо я подозреваю что по-другому мне придется менять все в уже готовых шаблонах выводов City.