akubintsev
@akubintsev
Опытный backend разработчик

Какие возможности у критерий и форм Symfony 2?

Начал недавно переходить с onPHP на Symfony 2.

Наткнулся на непонимание работы критерий в доктрине и формам.
Приведу примеры из onPHP, чтобы было понятно, чего хочу добиться в Symfony
$criteria = Criteria::create(Transaction::dao())
			->add(Expression::eq('order.payeeCompany', $this->getCompany()))
			->addOrder('order.id')
			->addOrder('dateCreated');

В данном случае имеется отношение 1 ко многим между Order и Transaction. Выборка идет относительно Transaction и с использованием свойств Order. То есть по сути делается джойн. Можно ли аналогично "путешествовать" между сущностями в Doctrine в рамках критерий? Критерии для меня очень удобны, потому что я могу с их помощью и ООП гибко конструировать различные запросы в зависимости от нужд классов.

Далее, что касается форм. Сразу оговорюсь, что с html-формами я не работаю. Мне нужна валидация и извлечение подготовленной структуры при работе с api.
$form
			->add(PrimitiveCore::identifierUuid(MerchantTransactionsReporter::USER_UUID, User::class))
			->add(Primitive::date(MerchantTransactionsReporter::DATE_NAME)->setDefault(Date::create('yesterday')))
			->add(Primitive::string(MerchantTransactionsReporter::ADDRESSES)->required())
			->add(Primitive::plainChoice(MerchantTransactionsReporter::TRANSPORT)->setList(['email', 'sftp'])->setDefault('email'))
			->addRule('checkRequiredFields', CallbackLogicalObjectSuccess::create($this->getStrategyRule()));

Вопросы:
1. В Symfony есть возможность указать для поля тип entity. Однако, мне не удалось найти возможность указать какое-либо иное поле для выборки, кроме основного идентификатора. Я плохо искал?
2. Как правильно использовать тип choice и указывать значение по дефолту? Читал документацию symfony.com/doc/current/reference/forms/types/choi... , использовал ChoiceList - не валидирует при правильных данных.
3. Можно ли использовать свои правила для валидации? Уточню: в последней строчке примера есть вызов замыкания $this->getStrategyRule(). Вот как оно выглядит:
private function getStrategyRule()
	{
		return function (Form $form) {
			if ($form->getErrors()) {
				return;
			}

			$hasUser = $this->hasUser($form);
			$hasCompanyEmails = $this->hasCompanyAndEmails($form);
			if (!$hasUser && !$hasCompanyEmails) {
				$form
					->markMissing(MerchantTransactionsReporter::USER_UUID, 'fill userUUID or (companyUUID and emails)')
					->markMissing(MerchantTransactionsReporter::COMPANY_UUID, 'fill userUUID or (companyUUID and emails)')
					->markMissing(MerchantTransactionsReporter::ADDRESSES, 'fill userUUID or (companyUUID and emails)');
			} elseif ($hasUser && $hasCompanyEmails) {
				$form
					->markWrong(MerchantTransactionsReporter::USER_UUID, 'fill only userUUID or (companyUUID and emails)')
					->markWrong(MerchantTransactionsReporter::COMPANY_UUID, 'fill only userUUID or (companyUUID and emails)')
					->markWrong(MerchantTransactionsReporter::ADDRESSES, 'fill only userUUID or (companyUUID and emails)');
			} elseif ($hasUser && !$hasCompanyEmails) {
				call_user_func($this->strategySetter, new MerchantReportUserStrategy($form));
			} elseif (!$hasUser && $hasCompanyEmails) {
				call_user_func($this->strategySetter, new MerchantReportCompanyStrategy($form));
			} else {
				throw new UnimplementedFeatureException("Unknown, unexpected state!");
			}
		};
	}


Я ни в коем случае не развожу холивар. У меня есть цель выделить из старого проекта кусок в новый и я решил это переписать с помощью Symfony.
  • Вопрос задан
  • 312 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы