On my symfony app, the time has come to add mailer functionality. Im always aware that that some new functionality justifiably goes into its own bundle. right now i want to add some mailer functionality so a user can check off some options, then send the items to a friend.
thinking ahead, i might also use that functionality in another bundle in this same app, which is a different part of the website.
so im thinking, i might want to put an email controller in its own bundle, but i know the swiftmailer bundle is already doing this, which i will be using.
so in the end im thinking its probably only a few lines of code i will need, and that may be best placed on the controllers of the specific parts of the website i need the email functionality on.
now comes the main reason i thought of making it its own bundle, twig templates for the email body's. do i want these templates dangling around in my other bundles? i guess it would make sense.
any suggestions?
It looks a bit overkill to create a bundle just for a few lines of code.
For your twig template you can put the shared template part inside app/Resources/views, which is shared for all your application. And put domain specific templates in domain specific bundles.
http://symfony.com/doc/current/book/templating.html#template-naming-locations
Whatever your email logic code should be inside a service wrapping swift mailer, like that if you need to switch mailing strategy, for example sending mails using an HTTP API, you just need to change this service, not all your controllers.
If you have some code to share between your bundles, may should you have an {App|Main|Core|...}Bundle containing all your "Single" services, that can be moved later in their own bundle if needed.
Anyway their is many approach for your global question :
You could use a single bundle containing all your business logic and externalize / decouple your technical / generic stuff inside bundles that can be shared between your apps
You could have an opposite approach with one bundle for technical stuff and many bundles for your business logic, may could it be harder to keep it low coupled
Or a mix of both
In my point of view the first approach works nicely for simple applications while second and third can be more domain oriented for bigger apps. The most important is probably to be consistant.
Related
I'm very new to symfony, but I'm sure it will help me to develop faster.
So here are my basic problem. I want to develop a application, that can be used by multiple clients. They will all have its own url. Something like this:
http://example.com/customer1
http://example.com/customer2
I see, that this is very easily done by editing the routing.yml - thats very cool stuff
app:
resource: "#AppBundle/Controller/"
prefix: /{customer}/
type: annotation
In the AppBundle, I can build the whole app within the controllers and symfony offer me the framework to do. It will have some editing routes, admin routes and much more.
But what if the any user call http://example.com/unkownCustomer/someSite
If a someSite route is defined it will cause a problem, just because there is no valid customer. Sure I can handle it, on each Action, but that isn't very smart. I was thinking about extending the Controller class from symfony, to add some base funktionality for example extended the render method to add some basic stuff like customer settings for example the customer name to add it automaticaly in the parameters array for twig, that I don't have to do it explicit in every controller. I think some security features also have to be implemented more generally, that one authenticated user that have a role don't have this role on other customer sites or is not authenticated.
But how I can inject some code before I run the action functionality targeting the route? And the big question - what should be the right way to do? Do have to change my mind doing this thing in symfony?
PS: Sorry for my poor english - hope you will understand my problem.
I learned a lot in the last 2 days - and that video completly answer my question in a very good way doing it in a it think right way!
https://knpuniversity.com/screencast/question-answer-day/symfony2-dynamic-subdomains
I have created an application where I can manage multiple websites. There are a lot of "extensions" (bundles) that can be used in the websites if they have the right to use it. The rights (which website can use wich bundles) are managed in my application and are saved in the database (with the namespace of the allowed bundle).
EDIT: When I call a website the bundles are loaded in the WebsiteKernel (a normal AppKernel that is commonly used by each website).
Each website has its's own app- and web-folder. So there is a separate app-cache for each website. Each website has it's own WebsiteKernel.php (= a normal AppKernel).
Now I want to register the allowed bundles for the currently called website dynamically in the its WebsiteKernel. In the post "Is it possible to dynamically register bundles in Symfony2?" this was done by looking into the bundle-directories. I would like to do this the same way but I only want to include the bundles that are saved as "allowed for this website" in the database.
To do so I need access to a repository to get the allowed bundle-namespaces. I thought I could do something like $this->getDoctrine()->getRepository('MyAppBundle:MyObject'); but I don't know how to call this function in the WebsiteKernel (= AppKernel). When I try to call $this->getDoctrine() I have a UndefinedMethodExeption. Of course I try to do this after the doctrine-bundle has been registered.
So the question is: How do I have to change the code in the WebsiteKernel (= AppKernel) to use $this->getDoctrine()?
Btw.: This two posts have a similar problem but they hasn't been answered yet.
Symfony2: How to dynamically register a bundle (and clear the cache) from other bundle's controller
Symfony2 register bundle and its routes at runtime
NOTE: The question was changed completely so this answer is no longer relevant. I should probably delete it but it does explain the problems with dynamically loading bundles.
The reason the questions have not been answered is that you basically can't do what you want.
First off, the doctrine entity manager has not yet been defined when AppKernel::registerBundles is called. It's a bit of a chicken and egg thing. Bundles are registered, all of the configuration files are processed and merged then the dependency injection service definitions(including the entity manager) are created and cached.
With a better understanding of the bootstrap process you could create your own database connection and pull bundle class names from a database. Of course the routing stuff has not been done yet so figuring out which bundles to load based on the route would mean further hacks.
The final major problem is that all of the configuration information ends up being cached. Take a look at app/cache. Rebuilding the cache is a time consuming process. Rebuilding the cache on each request would bring your production system to a crawl. And if another request comes in while the first one is being processed then you are really screwed as the second request will probably crash the first one when the cache is rebuilt.
The only approach that I know of is to setup an app for each website.
I'm developing a website which has a public part and a backoffice part. My intention is to have this bundle structure:
Acme/CoreBundle: common entities, repositories, services for both public and private
Acme/BackofficeBundle: controllers, forms, url... etc of the backoffice
Acme/FrontofficeBundle: same for the frontoffice
Then modify the app_kernel so the bundles of one or the other would be load depending on a enviroment variable of the virtual host.
Does this make sense or there is a better approach for this?
Thanks!
I think you should go with a different approach than the one you presented. You don't need to make this clear difference between backend and frontend. You should organize your code using other criterias than "frontend vs backend".
Let's say you have a shopping cart. So you might need some order, customer and product administration. You will have a frontend and a backend. I think the best practice in this case is, if you take the orders, to create an Acme\OrderBundle. Here you will keep everything that is order related. You can keep the frontend controllers in Controller/ and backend controllers in Controller/Backend/. You can create some services for backend area and keep them in Acme\OrderBundle\Backend, but generally your services/forms/etc. should not know about where are they used on, frontend or backend. The controllers should be used to make this distinction. This way you can create a service for order administration that is used on frontend and also on backend, forms that can be used on both ends etc.
This has been asked in similar forms here and here but it seems pretty important, and the framework is under rapid development, so I'm going to raise it again:
Assuming your login page needs to face the public internet, how do you prevent Meteor from sending all of the authenticated user templates to a non-authenticated client?
Example use case: You have some really unique analytics / performance indicators that you want to keep secret. You've built templates to visualize each one. Simply by visiting the login page, Meteor will send any rando the templates which, even unpopulated, disclose a ton of proprietary information.
I've seen two suggestions:
Break admin into a separate app. This doesn't address the issue assuming admin login faces the public internet, unless I'm missing something.
Put the templates in the public folder or equivalent and load them dynamically. This doesn't help either, since the file names will be visible from other templates which will be sent to the client.
The only thing I can think of is to store the template strings in the server folder and have the client call a Meteor.method after login to retrieve and render them. And if you want them to behave like normal client templates, you'd have to muck around with the internal API (e.g., Meteor._def_template).
Is there any more elegant way to do this?
I asked a similar question here:
Segmented Meteor App(s) - loading only half the client or two apps sharing a database
Seems to be a common concern, and I certainly think it's something that should be addressed sometime.
Until then, I'm planning on making a smaller "public" app and sharing the DB with an admin app (possibly in Meteor, possibly in something else, depending on size/data for my admin)
These 2 packages try to address this issue:
https://atmospherejs.com/numtel/publicsources
https://atmospherejs.com/numtel/privatesources
It uses an iron-router plug-in to load your specific files on every route.
The main drawback I see here is that you must change your app structure, as the protected files need to be stored in /public or /private folder.
Also you are supposed to use iron-router.
I am looking to borrow someone's brains (& experience) to figure out an optimum way to implement the below.
I am currently working on an application which will be used by many of our clients and will require UI customizations according to each client's requirements. Although the underlying java code as well as business logic will be the same, at runtime I would like to figure out (via some property) which client the application is running for and thus, choose the corresponding view and display the web page.
Currently, all I could think of is to create a custom ViewResolver (extending InternalResourceViewResolver) that will read the client name property and use this to resolve a view (eg: WEB-INF/jsp//account/myAccount.jsp) or default to another view (eg: WEB-INF/jsp/default/account/myAccount.jsp) if client property not present.
The issue I see here is that I might not want to overwrite all my JSPs for a particular client where the default view should be rendered. This will require an I/O Call to check the existence of the JSP file in the client's folder before reverting to the default. To counter the I/O I can even create a Map of overwritten JSPs at application startup but this will require an application restart on addition of new customized JSPs which again can be handled by exposing some service to refresh this Map.
So what do you guys think? Also, how will it affect redirects? Plz let me know if you need any further information about our setup or requirement.
Regards,
Sumit
You can use tiles to control the rendering of your view it has a default view resolver bundled with spring and you can extend that.
Define custom layouts, extend them and change it in case you want another behavior.
http://tiles.apache.org/
After waiting for more comments / suggestions, as JB suggested, going with my own solution as described in the question itself.
Thanks all for your help.