I've been trying to implement a Front Controller on a VBScript (ASP Classic) based system for a couple of days. I come from a ASP.NET MVC and Java background, where MVC implementations are kind common and mostly done by existing frameworks. On VBScript, however, there's almost nothing done in this area, so it is the reason why I'm trying to do it by myself. I used this and this article as a guide on how to implement it.
I believed at first that I'd need to define some constant parameters for each request, so I created 3:
class_command 'which command responsible to execute the correct class handler
action 'which method of the class handler to execute
action_params 'which parameters the action will need
Next, I defined a generic controller handler for treating the request:
Public Function Controller_Handler(action_params)
Its task is to extract the constant parameters (class_command, action, action_params) and treat any errors (I'll add later a filter to process it) that might come like absence of the constant parameters or authentication problems.
But soon I realized a problem: how will the handler know which command to call, since the request is a string? I can't simply converting it to class using reflection, because VBScript (I think) doesn't have a reflection library or built-in feature.
So I thought I could create a Switch Case like this:
Select action_Params.Item("action_params")
Case "command_A"
' Call Command A
Case "command_B"
' Call Command_B
.
.
.
Case "Command_X"
' And so on
End Select
But that would kinda procedural way to do it. Next I thought of creating a XML file which would map all the commands and other stuff.
So my question is: is this a good way of implementing a Front Controlller pattern, considering VBScript limitations? If not, could you provide a guidance (hopefully with some example, even a simple one) on how can I do it?
Moving from classic to .net/mvc I can share what I did in classic asp to try to emulate this behavior as closely as possible without making it too much of a maintenance issue.
Using URL Rewrite in IIS are my routes. I usually just make one route and direct/rewrite all inbound requests to one controller.asp page to simplify things and not have a bunch of rules and controller redirects directly in my URL Rewrite settings for maintaining it easier (for me).
Using Request.ServerVariables("HTTP_X-ORIGINAL-URL") in controllers.asp you can grab the actual URL that was entered, which return something like.. /real/url
In controllers.asp programatically call the view based on the entered url using Server.Execute("view1.asp")
I have one class file called routes.asp that is included in each model/class file, and helps me gather the URL properties oRoute.GetPath_FirstDirectory() and so on. The model/class file then uses this data to create its property values that can be consumed by the view. Using CLASS_INITIALIZE in each model/class to populate itself from the route/url, or it could also be done directly in the view.
In the respective view I include my class/model file (if even needed) using <!--#include file="class.asp"--> then simply open Set Model = new cModelClass to initialize and start using it in the view. I don't include the class in the controllers.asp because the view will not inherit any of the variables from controllers.asp when using Server.Execute() to the view. So I include it directly in the view.
Error handling can be at multiple levels here, but ideally its in the controllers.asp. Specific error handling is usually at the actual model/class CLASS_INITIALIZE to avoid redundant use of the class in the controller, since it's already going to be initialized in the view.
Now this is not exactly what goes in in .Net mvc, but it's the best way I've come up with, and easiest to maintain for me. Maybe others have other implementations, but this is mine and solely based on my experience. And so far, it's been working out pretty well.
Related
I am developing a simple CRMish application. Let's say I can create tasks and clients. Both can be created independently, but they can also be created in a process. I have a views called create.blade.php for these two actions.
When you are creating a task for example, at some point you have a button choose a customer / create a customer which opens a modal dialog (so you can pick a customer and assign it to a task in one step :)). And here it starts to get muddy. I want my form part from create.blade.php to be rendered in modal dialog and to do so I need to fetch this hitting my create action, which normally returns full form that extends master.blade.php.
How would you handle this kind of design problem? For now it would be a little, innocent switch or if before return view() in my create action but I know that it will look like spaghetti carbonara at some point.
My ideas are as follows:
ifs/switch as long as it's readable and it's only about returning
different views (but you know it will include logic, different
variables etc. at some point..)
move ifs/switch logic to some request class and call return
view($request->getView()) so my controller will be a little bit
cleaner and follow SRP
create different classes for "ajax" requests, and "normal" requests.
same as above but because the logic of fetching some data used in
form etc. are common for both of the scenarios I can create a base
abstract class of TaskController and than extend this for "normal"
request and "ajax" request scenario. This is most advanced idea, but
I think i follow SRP as well as I remove code duplication cause
fetching common data will be placed in abstract class
Do you have any other ideas of how to handle this?
I have ended up with a little conditional in my create.blade.php view.
#extends((( Request::ajax()) ? 'layouts.modal' : 'layouts.master' ))
According to #Kristo I wont overengineer, and stick with this simple & readable solution.
UPDATE
I have created a little extension, as I decided that I will not load my modals via Ajax but simply inject them on compile time. Here is the code :)
https://github.com/3amprogrammer/modal-blade-extension
I have some weeks since im using CI, but now I've found some problems about the structure of my project, I would like someone to give me some clues because I am kinda stuck, the problem is this:
I have my project MVC, so, I am dividing it into files (each per functionality) for example, there is a file with all the functions corresponding at login, and other with all related at post (it's an example), but now I am on a moment where I need to use login or posting into another part of the project, reading I found out i cannot call a controller from another, I can use the helper but still I will need to use a model, so I have to take that code and paste it into the controller where I'm calling the model and so on (and it's not good), I found out I can use modules, still I don't want to go over them until someone could give me an experience of this, i wouldnt like to change the project, is any way I could run all those controllers (i know i can use run:: I'm not sure if i can send parameters in it), any ideas please?
Thanks in advance.
Fair warning, this type of question will get shot down by many SO moderators, but I'll give you some tips regardless:
Controller actions are single-use. If you find yourself with duplicate code in multiple controllers (or, needing to call a controller function from another controller), that's a sure sign you should move that code to a model or library.
Models are object-specific, not action-specific. I wouldn't have a model dedicated to logins, unless you have multiple types of logins (most apps/sites just have member logins, but you might have administrators, etc. that are stored in a different table from the rest). Instead, have a User_model class, and make function login($email, $password) a method of that class.
Controller-to-model interaction should be very concise. If you find yourself with 30 lines of code passing data back and forth between the same controller and model, you might be trying to do too much with that one controller action.
Keep your models fat, controllers skinny, and views dumb.
I am new to MVC, CodeIginter. Instead of getting things easy, it needs lot of code to be written for a simple application. These are might be happening becouse I am new. So I have few confusions about this thing. Any kind of help is appreciated.
1) Methods are written in one controller can not be accessed in another controller classes. I have to write a new function for the same functionality.
2) To create website administration panel (back-end) in none mvc panel, we usually create it in a new folder. Is this thing possible in CodeIgniter? If not what about the admin (back-end)??
Let's try to clear some of your doubts about this.
1) Calling a controller's method from another controller is not possible, and it's whtouth meaning by the way.
A controller is supposed to get an action from the URL (which is routed by CI to the right controller for the task) and, based on that, decide which Model and which model's method needs be called to elaborate the data requested.
The model, then, hands back the result of this elaboration to the controller, which , in turns, decides to which view pass this results.
The view, eventually, is structured to get those datas and display them.
SO, as you can see, calling a controllers' method from another controller is nonsense, it would be like going to a page and finding another one instead; if you want to pass to another controller the request...well, there's the redirect for that.
If you find out you have the same functionalities in several moment, think twice:
What is a funcionality? Do you mean somehtin like "display posts" in controller "archive" and "display posts" in controller "news" ? they're hardly the same functionality; they can maybe share views, or models, but that's it.
For functions that doesn't relate to URLs, but involve some further elaboration (which might be wrong to do in Models) and are nonetheless called in a controller, you have library instead. Think at the "form_validation" library, which is called in a controller's method, but has its own peculiar (and encapsulated) functionalies. Ora a "session" library, or an "authentication" library
2) To create an admin panel the easiest thing is: create an "admin" controller (which is accesible then to www.mysite.com/index.php/admin), and put all the administration actions there, in its methods: create_page(), edit_page(), manage_users(), whatever.
In order to avoid people accessing it freely you need to build an authentication system, which, in its simplest and barabone strucutre, might be a check of wheter a session is set or not (maybe a check done at __construct() time).
But you can find nice Auth libraries out there already made, such as Ion Auth or Tank Auth (the 2 most popular to my knowledge)
Hope things are a bit clearer now. See also Interstellar_Coder's comment at this answer if you're interested in the modular HMVC approach.
1) Methods are written in one controller can not be accessed in another controller classes. I have to write a new function for the same functionality.
What's the functionality about? Perhaps you should write a library/helper instead, controller's logic should be limited to request flow or something else but not too complicated. For that, put the functionality in the model, or if more general, in library/helper.
2) To create website administration panel (back-end) in none mvc panel, we usually create it in a new folder. Is this thing possible in CodeIgniter? If not what about the admin (back-end)??
I don't get it, could you elaborate more?
Right now I am doing my testing by creating a controller for passing in the name of the file, parsing the file in the model and adding the necessary information added as a row in my database, which is then displayed on a page. I am then comparing the fields on the page to what the fields should be.
But this seems messy since the controller and display page were created only for the purposes of these tests. Is there a way to just feed the file name into a method in my model, and then run the usual tests against the database info itself?
I think it would be easier to answer this if we had a code sample (of the controller and model) to see why this shouldn't be handled in the standard rspec idiom.
Without knowing about your controller or model, I can at least say this: Yes, you can do that. The basic procedure to follow is to create your test file (if you need to), feed the name/path in to the test using a standard variable (yes, most likely hard coded, though it depends on how extensive you're planning to be), then test it against your database in whatever your standard way to do such things is.
After developing in CodeIgniter for awhile, I find it difficult to make decisions when to create a custom library and when to create a custom helper.
I do understand that both allow having business logic in it and are reusable across the framework (calling from different controller etc.)
But I strongly believe that the fact that CI core developers are separating libraries from helpers, there has to be a reason behind it and I guess, this is the reason waiting for me to discover and get enlightened.
CI developers out there, pls advise.
i think it's better to include an example.
I could have a
class notification_lib {
function set_message() { /*...*/}
function get_message() {/*...*/}
function update_message() {/*...*/}
}
Alternatively, i could also include all the functions into a helper.
In a notification_helper.php file, i will include set_message(), get_message(), update_message()..
Where either way, it still can be reused. So this got me thinking about the decision making point about when exactly do we create a library and a helper particularly in CI.
In a normal (framework-less) php app, the choice is clear as there is no helper, you will just need to create a library in order to reuse codes. But here, in CI, I would like to understand the core developers seperation of libraries and helpers
Well the choice comes down to set of functions or class. The choice is almost the same as a instance class verses a static class.
If you have just a simply group of functions then you only need to make a group of functions. If these group of functions share a lot of data, then you need to make a class that has an instance to store this data in between the method (class function) calls.
Do you have many public or private properties to store relating to your notification messages?
If you use a class, you could set multiple messages through the system then get_messages() could return a private array of messages. That would make it perfect for being a library.
There is a question I ask myself when deciding this that I think will help you as well. The question is: Am I providing a feature to my framework or am I consolidating?
If you have a feature that you are adding to your framework, then you'll want to create a library for that. Form validation, for example, is a feature that you are adding to a framework. Even though you can do form validation without this library, you're creating a standard system for validation which is a feature.
However, there is also a form helper which helps you create the HTML of forms. The big difference from the form validation library is that the form helper isn't creating a new feature, its just a set of related functions that help you write the HTML of forms properly.
Hopefully this differentiation will help you as it has me.
First of all, you should be sure that you understand the difference between CI library and helper class. Helper class is anything that helps any pre-made thing such as array, string, uri, etc; they are there and PHP already provides functions for them but you still create a helper to add more functionality to them.
On the other hand, library can be anything like something you are creating for the first time, any solution which might not be necessarily already out there.
Once you understand this difference fully, taking decision must not be that difficult.
Helper contains a group of functions to help you do a particular task.
Available helpers in CI
Libraries usually contain non-CI specific functionality. Like an image library. Something which is portable between applications.
Available libraries in CI
Source link
If someone ask me what the way you follow when time comes to create Helpers or Libraries.
I think these differences:
Class : In a nutshell, a Class is a blueprint for an object. And an object encapsulates conceptually related State and Responsibility of something in your Application and usually offers an programming interface with which to interact with these. This fosters code reuse and improves maintainability.
Functions : A function is a piece of code which takes one more input in the form of parameter and does some processing and returns a value. You already have seen many functions like fopen() and fread() etc. They are built-in functions but PHP gives you option to create your own functions as well.
So go for Class i.e. libraries if any one point matches
global variable need to use in two or more functions or even one, I hate using Global keyword
default initialization as per each time call or load
some tasks are private to entity not publicly open, think of functions never have public modifiers why?
function to function dependencies i.e. tasks are separated but two or more tasks needs it. Think of validate_email check only for email sending script for to,cc,bcc,etc. all of these needs validate_email.
And Lastly not least all related tasks i.e. functions should be placed in single object or file, it's easier for reference and remembrance.
For Helpers : any point which not matches with libraries
Personally I use libraries for big things, say an FTP-library I built that is a lot faster than CodeIgniters shipped library. This is a class with a lot of methods that share data with each other.
I use helpers for smaller tasks that are not related to a lot of other functionality. Small functions like decorating strings might be an example. Or copying a directory recursively to another location.