问题描述
我的应用程序中有一个有点复杂的定价机制 - 这里有一些我的业务规则来设置阶段(实体是粗体):- >或客户群。
- 产品有时可以有一个或多个附加选项有价格 或 价格规则。
- 产品用户选择了一个唯一加法,这本质上是一个价格和整数。
现在我有一个EntityRepository for Price Points 来确定基本产品的正确价格点。 唯一加法和选项也一样。
PricePointRepository
public function getThePrice($ Product,$ qty,$ Website,$ Customer = null)
{
//所有获得产品价格的逻辑对于这个给定的例子在这里。好。
}
控制器(简体)
public function indexAction()
{
$ Product = $ em-> dostuffwithpostdata;
$ qty = POST ['qty']; // inb4insecure trolls
$ Website = $ em-> dostuff();
$ Customer =(如果用户登录,使用$ em返回其对象,否则为空,因为它是客人或公众); //这里没有商业逻辑,只需了解请求。
$ price = $ em-> getRepository(PricePointRepository) - > getThePrice($ Product,$ qty,Website,$ Customer);
$ Options [] = $ em-> dostuffwithPOSTdata;
$ optionsPrice = 0;
//下面是与产品定价直接相关的一些逻辑。
foreach($ Options as $ option){
if($ option-> hasRule()){
$ optionsPrice + = $ ruleprice; //当然还有一些其他的东西)
} else {
$ optionsPrice + = $ em-> getRepository(OptionPricePoints) - > getPrice($ option-> getID(),$ qty) ;
}
}
$ uniqueAdditionPrice = $ em-> stuff;
$ finalprice = $ price + $ optionsPrice + $ uniqueAdditionPrice; //这是关于我如何价格这种类型的产品的逻辑!
$ unitprice = $ finalprice / $ qty;
// twig东西来呈现和显示$ finalprice,$ unitprice,$ uniqueAdditionPrice
}
这只是产品页面。当这个逻辑需要重复使用时,当我进入购物车,保存订单等时会发生什么。正如你所看到的,我使用Doctrine来根据我的业务逻辑在存储库类中提取数据。
我很乐意欢迎urdoingitwrong的答案,因为我真的认为这是错误。如何解决这个问题?美丽的东西将是一种基本上这样的服务:
$ pricer = getPricerService-> Pricer($ Entities,$ postdata ,$等);
$ unitPrice = $ pricer-> getUnitPrice();
$ totalPrice = $ pricer-> getTotalPrice();
$ optionsPrice = $ pricer-> getOptionsPrice();
但是,我不知道如何在Symfony / Doctrine里面做到这一点,尤其是Doctrine在控制器中访问存储库。
您应该将所有可重用的业务逻辑归功于一个服务,以便不同的控制器可以重新使用代码。
您是否已经签出了如何创建服务文档:
尽管如此,我会给你速度下降。
在config.yml中,您需要定义您的服务:
服务:
pricing_service:
类:Acme\ProductBundle\Service\PricingService
参数:[@doctrine ]
然后你只需要做一个沼泽的标准PHP类来表示你的服务:
命名空间Acme\ProductBundle\Service;
class PricingService {
private $ doctrine;
函数__construct($ doctrine){
$ this-> doctrine = $ doctrine; //注意,这是使用config.yml
$
//中的参数注入的。现在其余的函数到这里,如getUnitPrice等。
最后要从控制器获取您的服务,您只需要执行以下操作:
$ pricingService = $ this-> get('pricing_service');
还有其他方法可以模块化服务,例如不将所有服务转储到config.yml中,但所有这些都在文档中解释。还要注意,您可以将任何其他服务注入到您的服务中,以便您需要像参数之类的东西:[@doctrine,@ security.context,@validator]
所有的东西,甚至: [@ my_other_service]
。
我怀疑你的其他问题注入EntityManager你可能已经发光了,这是要走的路!
希望这对你来说还是有用的!
I have a somewhat complex pricing mechanism in my application- Here are some of my business rules to set the stage (Entities are bolded):
- A Product may have unique Price Points for a given Customer, Website, or Customer Group.
- A Product can sometimes have one or more additional Options that may have their own Price Points or Price Rules.
- A Product has one Unique Addition selected by the user, which is essentially a price and an integer.
Right now, I have an EntityRepository for Price Points to essentially determine the correct price point for the base product. The same goes for the Unique Addition and the Options.
PricePointRepository
public function getThePrice($Product, $qty, $Website, $Customer = null)
{
//all logic to get product price for this given instance goes here. Good.
}
Controller (simplified)
public function indexAction()
{
$Product = $em->dostuffwithpostdata;
$qty = POST['qty']; //inb4insecure trolls
$Website = $em->dostuff();
$Customer = (if user is logged in, return their object with $em, otherwise null as it is a guest or public person); // No business logic here, just understanding the request.
$price = $em->getRepository(PricePointRepository)->getThePrice($Product,$qty,Website,$Customer);
$Options[] = $em->dostuffwithPOSTdata;
$optionsPrice = 0;
//Below is some logic directly related to pricing the product.
foreach($Options as $option) {
if($option->hasRule()) {
$optionsPrice += $ruleprice; //after some other stuff of course)
} else {
$optionsPrice += $em->getRepository(OptionPricePoints)->getPrice($option->getID(),$qty);
}
}
$uniqueAdditionPrice = $em->stuff;
$finalprice = $price + $optionsPrice + $uniqueAdditionPrice; //This is logic related to how I price this type of product!
$unitprice = $finalprice / $qty;
//twig stuff to render and show $finalprice, $unitprice, $uniqueAdditionPrice
}
That's just for the product page. What happens when I get to the cart, saving the order, etc, when this logic needs to be reused. As you can see, I use Doctrine throughout to pull data based on my business logic in the repository classes.
I gladly welcome urdoingitwrong answers, because I really do think this is wrong. How do I go about fixing this? Something beautiful would be a service that essentially goes like this:
$pricer = getPricerService->Pricer($Entities,$postdata,$etc);
$unitPrice = $pricer->getUnitPrice();
$totalPrice = $pricer->getTotalPrice();
$optionsPrice = $pricer->getOptionsPrice();
But I have no idea how to go about doing that inside of Symfony/Doctrine, especially the way Doctrine and Repositories are accessed in Controllers.
You're correct that you should have all your re-usable business logic farmed off to a service so that different controllers can re-use the code.
Have you checked out the "how to create a service" documentation:
Service Container Documentation
I'll give you the speed run-down though.
In config.yml you need to define your service:
services:
pricing_service:
class: Acme\ProductBundle\Service\PricingService
arguments: [@doctrine]
Then you just need to make a bog standard PHP class to represent your service:
namespace Acme\ProductBundle\Service;
class PricingService {
private $doctrine;
function __construct($doctrine) {
$this->doctrine = $doctrine; // Note that this was injected using the arguments in the config.yml
}
// Now the rest of your functions go here such as "getUnitPrice" etc etc.
}
Lastly to get your service from a controller you just need to do:
$pricingService = $this->get('pricing_service');
There are other ways you can modularise the service such as not dumping all your services into config.yml but all of that is explained in the documentation. Also note that you can inject any other service you wish into your service so if you need stuff like arguments: [@doctrine, @security.context, @validator]
you can do all that stuff or even: [@my_other_service]
.
I suspect from your other question on injecting the EntityManager you may have already gleamed this was the way to go though!
Hopefully this was still useful to you!
这篇关于Symfony2 / Doctrine,必须将业务逻辑放在我的控制器中?并复制控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!