what is the best structure for a project in codeigniter and how to use it? - model-view-controller

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.

Related

View and ViewModel best practice

I have doubts whether every view should have its own ViewModel or should I pass the plain model where there is no need for ViewModel? (What concerns me is that if I start to mix these two concepts, then I will end up with jungle later on)
I tried to google it but no one talks about that, every post I run into just explains the purpose of ViewModel and I know that the main purpose of ViewModel is so you can pass multiple models to view.
It depends.
In many use cases the main purpose is not to expose fields to being bound on form submission that the user shouldn't be able to update. I wouldn't slavishly create them when not needed but it depends on the developers and their level of understanding on when and why you use viewmodels vs domain/ef models. Also application code base size makes a difference.
Maybe you need select lists, maybe you want to convert some properties to different types. Lots of reasons to use them. However it is more code and mapping code even if you use a tool like AutoMapper. So they cost time to implement but maybe they fix problems and save other time? Maybe they fix a security problem? Maybe doing them all the as view models helps juniors understand? Maybe you would rather do the setup of a viewmodel at start than convert code later when it is really needed?
Consistency can help but doing a bunch of extra work may not be worthwhile. Best practice for me isn't best practice for you.
Consider the costs and benefits for your project and team . E.g. maybe your project is internal and no one is going to try to hack via adding data to submission
There are couple of reason to choose ViewModel over DomainModel.
1) First thing first is the security. Imagin you have a view for changing the password. If you pass the domain model to the view. probably you are exposing a lot of properties which is not necessary and it may cause a security problem. There is no reason to expose properties like LastLoginDate, IsActive, IsEnabled, NumberOfFailedLogin and so on for just changing the password.
2) The second reason is reducing logic from the view. If you pass a Domain class to the view, Possibly you need to add some extra logic for hiding extra properties or shape it as you like or adding logic based on the route and etc.
3) Because of the architecture. Exposing domain model to the view cause tightly coupling between your presentation layer and domain model which is not good at all.

In Laravel, what is the advantage of single action controllers?

A topic about single action controllers is in the laravel documentation:
https://laravel.com/docs/5.5/controllers#single-action-controllers
My question is, what is the use case where you will use this controllers? How will you structure your controllers if you opt to use single action controllers for all your controllers?
Michale Dyrynda seems to sum up the pupose of Single Action Controllers in his blog: https://dyrynda.com.au/blog/single-action-controllers-in-laravel
Conclusion
Single action controllers are an effective way to wrap up simple functionality into clearly named classes.
They can be used in instances where you're not necessarily following a RESTful approach; be careful not to separate multiple actions for a single entity across multiple controllers.
Where you might have previously used a single controller for multiple static pages, you could consider separate named controllers for each static pages.
You can add other methods to this class, but they should be related to the single action this controller is responsible for.
He also states that, you should only use these when you only need a single action for an entity:
You may consider naming the controller ShowPost as a way of being explicit about the controller's intent but I'd suggest caution with this approach; if you start seeing ShowPost, EditPost, CreatePost, etc controllers creeping into your codebase, I'd reconsider the RESTful approach. More controllers never hurt anybody, but we should be smart about when this is done!
This is an intresting question and my answer is not related to laravel, but to the single vs multiple actions per controller.
I have found when trying to find the use case for a pattern that is new, is to ask the inverse questions, in this case, when is the use case of multiple actions per controller make sense?
The answer usualy comes to:
You have an object that has crud operations (because your using sql)
and its convenient to place all the stuff related to that object in
one spot.
This is akin to the answer of "I have a hammer, so everything is a screw" and IF your domain is as simple as a thin layer over a crud database, then that is the use case for multiple actions per controller.
What I have found is that any amount of complexity blows up the controllers, no matter how good your model is. The reason is CRUD opperations are apart of your model, not your controller.
We usually think that we will map nicely to a CRUD model in our controller, there are many front end frameworks that work amazing at that, untill....
Look at the most common aspect of applications, users. In the setup your going to have index of users, which I don't know who would look at that page besides admins, and they usualy want extra information. so for the index action, you need admin custom authentication.
Then creation, well, it does not make sense to have an user create an user, you need to ensure the user is not authentication.
Now we talk about reading. What data an admin, other users, current user, and anon user can see is massivily differnt, and will slowly build up in complexity.
Then delete, this is normally rare action, and on some models not needed, but you still put it up, because, well you have a hammer.
The update, do you put password updates in here too? what if the user forgot there password? do you put that in here? No, you make a new action called forgot password.
Well now you need update password action. What goes in the update is usually a gigantic mess of hell after a year.
Each pattern has its pros and cons, my general advice is to do multiple actions per controller when your system is trully CRUD OR you will not have to maintain the project for more than a year. If you have any amount of complexity that will have to maintained, avoid the model leaking into the controller and keep them seperate.

Laravel Create Function to be used in different Controllers/in the same Controller

It's more a general question, I want someone to point me to the direction I should go.
1) FUNCTION FOR SAME CONTROLLER: I have two methods: Store and Update in the same controller. They both should contain some complex request validation (which I can't do via validator or form request validation because it's too complex). This means for me now using the same code twice in two methods... How can I take this code, create a function and use it in both Store and Update methods just with a single line, like:
do_this_function($data);
2) FUNCTION FOR DIFF. CONTROLLERS: I have another code which I use in many different Contollers. It transliterates Russian letters into Latin ones ('Сергей' = 'Sergey' and so on). How and where should I register this function to be able using it in different Contollers?
transliterate_this($data);
I have read something about helpers. Should I use them? If you an experienced Laravel develper and say so, I will read everything about them. Or, if you advice something else - I'll read about that.:) I just don't want to spend time reading about something useless or "not right way to-do-it".
Appreciate any help!
1) You could create a form request validation or you could just create a private function that would handle the validation and return the result.
2) You can create a helpers.php file, see here, and you put your translation function inside. Then you can call it from anywhere:
In a controller transliterate_this($data);
In a view {{ transliterate_this($data); }}.
You can do complex validation even inside a FromRequest. You can override the getValidatorInstance for example, or any other method from the base class to plug your validation logic on top of the basic validation rules. Else just consider making an external class to handle that complex validation and inject it in your controllers using Laravel's IoC container.
You should create a facade to provide that feature. Then you can easily use it anywhere (and additionally create a helper method for it if that makes you feel better). Something like Transliterate::toLatin($str)
everyone! Thank you all for great answers. But I have discovered that the problem was that I didn't know anything about Object-Oriented Programming.
(Ans I was working in Laravel:)).
After I took an Object Oriented Bootcamp from Laracasts, I started 'seeing' how Laravel actually works and I know can easily create methods inside classes and use them in other classes.
https://laracasts.com/series/object-oriented-bootcamp-in-php
(of course, you can read something else on OOP, but Jeffrey Way has really outstanding explanation talent!)

Which is better in Laravel - use Input::get() in Controller or Model?

I wanted to ask, looking from the 'best practices' side, which solution is better, getting a form data in Controller and passing it to Model, or retrieving it directly in the Model?
I use the first solution, which makes your controller methods very long and ugly, but I think it is still the right choice. But recently I have seen some other projects source code where the form data is retrieved in model, but it seems that it breaks the rule, where the model should not know, where the data comes from.
So which is the better practice?
As #lukasgeiter said in the Comments, I also say this would typically be done in the controller.
You may want to have a look at the corresponding laracasts on
MVC
Models
Controllers
Basically, you already said it. Models are just kind of "storage-interfaces" while Controllers are places, where the logic happens.
Also, have a look at MassAssigment, which cannot be done within the Model itsself but in the controller. This might be of interest in your case (without knowing the details).

Codeigniter Inter Controller Communication

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?

Resources