How to organize my code? - laravel

I'm still in a learning phase with PHP and Laravel 5 and since I upgraded to L5, I struggle with where my code belongs to. There are so many files and folders which seem to have the same purpose or at least are very similar. There are Commands, Controllers, Events, Services, Requests, etc. I give an example with my workflow and where I would place the code and I hope you guys can comment on that and correct/help me.
Situation
I want to register a new user in my application and send a welcome e-mail when he registered successfully.
Workflow
Controller (UserController): Returns requested view (register).
Request (RegisterRequest): The "RegisterRequest" validates the entered data.
Controller (UserController): Passes the validated data to the "UserRegistrar" (service) in 'App/Services'.
Service (UserRegistrar): Creates a new user and saves it to the database.
Controller (UserController): Fires the "UserWasRegistered" Event.
Event (UserWasRegistered): This Event call the "SendWelcomeEmail" Command.
Command (SendWelcomeEmail): This Command will send/queue the welcome e-mail.
Controller (UserController): Redirects the user to a view with the information that he has been registerd successfully and a message has been send to him.
Logic
Okay, let's discuss some logic:
Controller:
Doesn't hold much code.
Mainly there to return views (with requested data).
Handles workflow and "connects" modules (Services, Requests, Events).
Request: Validates the data for a specified request
Service: A service "does" something. For example it's doing requests to the database.
Event: An Event is a central place to call one or more tasks if it is fired (SendConfirmationMail, SendWelcomeMail).
Command: Mainly there to handle the logic for ONE certain task. For example sending a confirmation mail. Another command will hold the logic for sending the welcome mail. Both commands are called in the Event described before.
Repositories: What is that?!
So this is what I understand. Please help me and feed me with information.
Thanks,
LuMa

Your question is a little vague and will likely attract downvotes as being "too broad". That said, here's my take on this...
The biggest issue I see is that your application structure is very different from the recommended L5 structure - or even the standard MVC structure - that it's no wonder you're getting confused.
Let's talk about your "Logic" section:
controller - you're on the right track here. The controller is the glue between your models and your views. It can do some processing, but most should be offloaded to classes that handle specific tasks.
request - what is this? L5 includes a Request class that includes methods for examining the HTTP request received from the client. Are you talking about subclassing that? Why? If your idea of a "request" class is primarily concerned with examining input, you can either do that in your model (ie. validating stuff before sticking it in the database) or in your controller (see the L5 docs on controller validation)
service - again, what is this? You talk about "doing requests to the database", but L5 provides a class for that (DB). At a higher level, database access should primarily be done through models, which abstract away most of the low level database access. As for other services, what I usually do is create libraries to perform specific processing. For example, my application has a particular third party project management application that it accesses via an API. I have a library for that, with methods such as getProject or createProject.
event - An event is a way of ensuring that some code is called when the event happens, without a whole lot of messing about. It sounds like you have the right idea about events.
command - again, it sounds like you have the basic idea about commands.
repositories - these are way of abstracting the connection between a resource (primarily the database, but it can apply to other resources too) and the code that uses the resource. This gives a way to switch the underlying resource more easily if you (for example) decide to change database servers in the future. They are optional.
You also haven't mentioned anything about models. L5 provides an excellent way to deal with your data in understandable chunks via Eloquent models - this will make your life much easier.
My suggestion is this: start small. Build a simple MVC application with L5 - A model (to save some data), a view (to display the data), and a controller (to put the model & view together by handling the client request). Once you have that, start extending it.
There are tutorials out there that will give you this basic structure for Laravel - most are for Laravel 4, but see if you can follow the basic ideas and build something similar for Laravel 5.

Related

Where to put ajax request in Ember tutorial app?

I want to add "Weather: 24C" to the rental-listing component of the super-rentals tutorial app.
Where would be the "best-practices" place to put this ajax request?
Ember.$.getJSON(`http://api.openweathermap.org/data/2.5/weather?q=${location}&APPID=${apiKey}`)
.then(function(json) {
return JSON.parse(json).main.temp;
});
Do I need to add a component, add a model, add a service, add a second adapter, modify the existing adapter? Something else? All of these? Is the problem that the tutorial uses Mirage? I ask this because when I think I'm getting close, I get an error like this:
Mirage: Your Ember app tried to GET
'http://api.openweathermap.org/data/2.5/weather?q=london&APPID=5432',
but there was no route defined to handle this request.
Define a route that matches this path in your
mirage/config.js file. Did you forget to add your namespace?
You need to configure mirage to allow you making calls to outside in case mirage is active; what I mean is using this.passthrough function within mirage/config.js, that is explained in api documentation quite well.
Regarding your question about where to make the remote call is; it depends:
If you need the data from the server to arrive in case a route is about to open; you should prefer putting it within model hook of the corresponding route.
If you intend to develop a component that is to be reused from within different routes or even from within different applications with the same remote call over and over again; you can consider putting the ajax remote call to a component. Even if that is not a very common case usually; it might be the case that a component itself should be wrapped up to fetch the data and display it by itself for reusing in different places; there is nothing that prevents you to do so. However by usually applying data-down action-up principle; generally the remote calls fall into routes or controllers.
Whether using an ember-data model is another thing to consider. If you intend to use ember-data; you should not directly use Ember.$.ajax but rather be using store provided by ember-data and perhaps providing your custom adapter/serializer to convert data to the format ember-data accepts in case the server do not match to the formats that ember-data accepts. In summary; you do not need to use models if you use pure ajax as you do in this question.

Handling Action errors/output inside out-of-the-box Workflows

I am working on designing a lengthy approval system in CRM using a combination of OOB workflows (designed using CRM UI Workflow Designer) and custom actions (actions written using .NET code). Idea is to keep the entire branching/simpler logic in OOB workflow and call custom Actions wherever necessary. However I have few questions with this approach:
How can I handle run-time errors generated in the action code?
For example, one of my Actions contain the code to push data to an external system via web service. In case this web service call fails, I need to perform some steps in the parent workflow.
How can I handle 'if conditions' which can't be handled by 'Check Condition' step? For example, suppose that before performing a certain workflow step I need to check some data which can't be queried within CRM. I can create an Action which will return true/false based on the custom logic which can then be checked in parent workflow.
An alternate approach would be to use plugins but I am inclined towards using OOB functionalities as much as possible. Any inputs would be helpful.
First of all let's clear the semantics, because I'm not sure if you understand what are you talking about - there are Actions (you can refer to them as custom actions, but then you should refer to every workflow you create as custom and I figured out of your post that you are describing them as OOB, which also is semantically wrong - every workflow you create is a custom workflow, maybe it's using OOB steps, but that's a different story) and Custom Workflow Activities. I'm assuming that you want to use Custom Workflow Activities, because the are more suited for what you are trying to achieve here. Also you tagged your question as CRM 2011 and CRM 2013 - not sure what you meant, because Actions were not available for CRM 2011.
So basically Custom Workflow Activities can have Input and Output parameters. Output parameters are answer to both your questions, because you can use them to get the error message after your custom processing or use then in conditional statements later in your workflow. Output parameters can be defined like that:
[Output("Error message")]
public OutArgument<string> ErrorMessage { get; set; }
You can find more examples here:
https://technet.microsoft.com/en-us/library/gg327842.aspx
You can of course set this properties simply by calling
ErrorMessage.Set(executionContext, messageText)
So now when you define your workflow, wherever you need something not configurable in OOB blocks, you can put your Custom block, after it's done simply check it's output for the error (this is just an example, you can pimp it up by adding additional output parameters, to make it more generic), if it's empty then do something, if not then do something else for example send email with the error message. It all depends on what are you trying to achieve.
Actions are serving different purposes, they are useful to create a logic that can be easily called through plugin or javascript (webAPI) and allows you to also put a plugin on it alongside doing everything within one transaction. Maybe it will be useful somewhere in your workflow, but as far as I remember in CRM 2013 actions could not be called from a workflow...
UPDATE:
Ok so if we are dealing with CRM 2016, we can call Action from a workflow. What is best in this situation really depends on the scenario and what we are trying to achieve, but to make it easier to decide let me highlight main differences:
1) Activities are simply a blocks of code that can be put inside your workflow. Actions by themself are not code, they are custom Messages that you can call. Of course you can register a plugin on this custom Message and do there any custom logic you want, but this is another step to take
2) Actions can be run in transaction, Activities not (but you can run Activities inside Actions, so in this case they can run in transaction)
3) Actions can be called directly from Javascript, plugins and workflows. It's a great thing, but if you will make let's say 10 custom Actions which you will be using ONLY inside you one workflow, they will be visible when you will be registering plugins (and also any js developer will be able to call them with JS)
So basically Actions are a big, fat feature that can serve many purposes (including running Activities on their own!), Activities are much simpler but in your case they will also do their job. So you should ask yourself questions:
Do I need my logic to run inside transaction?
And
Do I need to call this logic somewhere else than my workflow?
If you have any "Yes" then go for Actions, of no, then go for Activities, because you will be overcomplicating things without any good reason.

Where does logging fit in the model view controller architecture?

I would like to log communications activity and, as part of logging, display communications history in a window on the screen. I don't want the communications modules to know about the screen of course, but any method can write to the log. The logging module then routes the information as appropriate (screen, file). Is logging considered part of the model?
Whether the commands, that are executed by instance, are logged or not should not affect the instance itself. Which means that if, for example, you want to log operation performed by controller, the controller itself should not be doing the logging or in any other way be aware that it gets logged.
The much better option is to have the instance decorated. The decorator would require the original instance and a logger injected thought constructor.
Assuming that your MVC components (views, controller and structures from mode layer) are already created via factory, this would be the best "level" at which you switch between logged and unlogged mode.
TL;DR
No. Logging is not part of MVC triad itself.

Oracle CRM On-Demand - Use Tasks Status to update Service Request Status

We're using CRM On-Demand for our Service Group and I'm running into an application limitation and am wondering if anyone has a workaround or just some general ideas on how to accomplish our goal.
In the application, our major focus is around the Service Request and driving for users to create Tasks for all Activities related to working towards closure. For example, a customer calls in and we need a technical resource to make a return call to diagnose the issue in detail, so a Task is assigned to that resource. Once that Task has been marked as completed, I'd like the Status to be updated. I tried creating a workflow using JoinFieldValue(), which wasn't working. I tried a more basic approach and tried to just have a field on the Service Request be populated with the Status of the Task, but that did not work either.
Upon further investigation in the Help File, there is a relationship from the Activity object to the Service Request object, but not one the other way.
So, has anyone else run into this limitation and found some other method to have a Status change on the Task update the Status of a Service Request?
(Also, I'd like to try and avoid writing a custom web service for this purpose, which is why I'm trying to use the tools in the app)
Thanks in advance for any ideas!
actually, if I well understood your issue is related on workflow cross object.
OCOD doesn't manage this type of workflow when you need to use workaround.
In order to cover a cross object worklflow you have many possibilities:
webservices as you said, but you could imagine a js code that will run WS and hosted directly into OCOD (in R19 you could hoste that in Client Side extension). That could be a good solution
Another one could be using Report with a custom look up functionnality with the usage of "Callback" function
I would prefer the 1st solution.

strutrs2 and ajax(Displaying dynamic value on jsp)

Im pretty new to struts2 and Ajax ,Actually i have a drop down menu in JSP lets say first.jsp, When user select a choice from dropdown menu,I am calling a function of Action class lets say Method1.In this method i am fetching some value from DB(lets say:a,b,c) and one value from java memory lets say d.Then I am forwarding to second.jsp and display all the parameters(a,b,c and d) in tabular format.
Now problem is that the parameter d is dynamic ,this is updating by some other application and if its change then I have to show it on JSP wihout any action.
One solution is I use in second.jsp , so after interval of 10 second again Mehod1 will call and it will fetch value(a,b,c) from db and updated value of d from java memory. and disply it to second.jsp.But in this case i am unnecessary retrieving value from db while my purpose is just to get value d from memory.This is working but this is causing my application to slower.
Can any body suggetst some other solution? or can i do it using ajax and how?
Any other advice? any help is appreciated.try to be more clear, i'm in lack of ideas in this problem, even it sounds like a classic :I have spend hours trying to play around with this but have got nowhere
Okay... What you're asking is a little fuzzy so let me rephrase:
You have a user (USER1) who opens a web page and sees some data.
You have a second user (USER2) (who may be an application) who is able set a value from time to time.
When USER2 updates that value you want USER1 to see it change in their open browser window?
If this is the case you need to understand basic ajax. For that get these demo applications working:
This example uses dojo and perhaps the S2 ajax tag lib I don't remember I prefer not to use ajax tags (as they are deprecated and prefer jquery for ajax):
http://struts.apache.org/2.x/docs/struts-2-spring-2-jpa-ajax.html
This example here shows a very similar application but using jquery, no tag library, upgraded to Spring 3, it still needs polish:
http://www.kenmcwilliams.com/Downloads/
Now that you know how to get data via ajax, look at the request with firebug. You'll see that the request is just like a typical function call, the browser keeps waiting for the data to come back.
What you do is simply not return from the action until new data is provided. This is called long polling see: http://en.wikipedia.org/wiki/Comet_%28programming%29#Ajax_with_long_polling
If you have not written a simple chat program, using just terminal windows I recommend you do so. Two windows per client (client-send, client-receive windows) and you'll need a server program. I remember hacking one together in a few hours using _Thinking In Java 2nd Edition (Later books took out the networking section if I remember correctly). Anyways between understanding client server interaction and long polling will let you get things working. It would be fun to extend the simple terminal based chat application to a S2 ajax chat application. Would make an awesome tutorial! PS: This is just an application of the producer/consumer problem (If you understand that then I guess you don't need to do the fun exercise).
The interfaces would look very pretty if the server was managed by spring. I know there must be nice servers already written but I am not familiar with any, but would love to hear of one.

Resources