So I've been working on an PHP MVC for a client for about 3 weeks now, I've got pretty far.
I'll explain a small part of the system.
There are three types of users, Fitters, Agencys, and Admins.
these can all log in and have limited functionality, admin obviously has all functionality!
The admin can add, edit and delete users, jobs, stock blah blah the usual.
The way I've set it up so far is like so...
The query string is like: /admin/users/?method=agency&action=add
This will call the admin controller, and call the users function.
The users function will then call the users model.
The users model contains functionality to add, edit, delete, admins, fitter, and agencies.
action=add&method=admin will call add_admin() which will dynamically return a form for admins
action=edit&method=fitter will call edit_fitter() which will dynamically return a form for editting fitters
Now I was wondering...
Would it be better for me to have an ADD class. with ALL the add methods like, add_fitter, add_agency, add_admin, add_job, add_stock etc... and then have a class for EDIT, a class for DELETE, and a class for VIEW ???
Would this be a good way?
I thought that by doing this, I can limit the dependancy on classes like the USERs class.
Because the users class adds, edits, deletes, inserts, updates and views fitters, agencies, and admins. So the user class needs a Validator, a database, a Form class that returns html forms for adding and editting etc etc.
However if i had ONE class for ALL the adding, then it would eradicate the dependancy for a validator? because the add class would be responsible for returning the form. Nothing else
The reason I'm asking this question is because I'm new to MVC. and I dont want to spend the next couple of hours changing all my code, and then realising that theres a problems with my proposed pattern.
So i'm just asking you kind people, can you foresee a problem with this method?
is this how its usually done?
or is this method steered clear of for a reason?
ANY advice or tips will be GREATLY appreciated!
Just to be clear... I'm asking whether I should have separate classes for Add, Edit, Delete and view
Alex
I think the best way is store the access level of the user (session, etc), and render the page according to what was stored in the session. Urls need to be only /admin/users/?action=add
Or
admin/user/edit/?id=27
router/controller/action/?param1=value1
Just if anybody was curious, i did implement my mvc this way and it's much better!
Related
I've had a quick search on Stackoverflow but not really found an answer to a question that I have. Sorry if it's already been answered and I've missed it!
I'm working on an application, and similarly to Facebook, there will be 'notifications' but in my case it'll be items that require actions from the user. It would just be a 'count' of the actions that are required and nothing else.
I've followed a fat model, skinny controller approach through my application and so far so good. I have a good idea of what goes where, and when to use a plugin, app model, app controller, etc.
However, I'm a little confused about where to put this notification/action 'count'. I'm guessing either afterFilter() in the app_controller.php file, but that's just a guess. I'm just looking for the most efficient place to put it.
So, where's the best/fastest/most efficient place to put this count call?
Thanks!
Kingsley
EDIT: I just realised it's worth pointing out that this particular call is on a model. So, at the moment I have to load that model, and then call it.
The ideal place is in an Element. You can then use requestAction() to tell it where to retrieve it's data from.
The Element is placed into a view (or used to display a Flash message). Within it, it pulls it's data (requestAction) from a Controller's Action. That action get's it's data from the Model of your choice just like you would in any other action. This allows complete separation of concerns (ie MVC).
I am facing some confusion because i have decided to convert from procedural to oop, I Find it more efficient.
So anyway I've got some questions i hope i find answers here :)
Let's say am working on a php Registeration System which requires
1-Signup process
2-Activation Process
3-Login process (which requires)
Validating inputs
Validating Sessions, etc
The questions is: Should i make class for every process Or i can combine all of them into one class named 'User', with methods to login, signup, activate and so on, Or can i make 1 class named USER which has user's properties, and signup, login classes extends it ?
Should i use separated classes for Sessions, Validating etc ? or just normal Checking inside the main class
Should i Separate ADMIN classes from normal classes ? meaning I have a USER class, which has methods, to login user, signup user etc, should i add more functions for admin like DELETE user, UPDATE user ? or separate it from the normal classes
You should make a User class with different functions for login signup and whatever.
You should separate different functions into as many classes/objects as you feel suits. For instance, with your User class you might have a Session class which you use within your User class to do the session management stuff. You could also create a Person class which User inherits from. This can have functions like printFullName and such, whereas the User class has auth specific stuff like login and register.
Again, its up to you. You can do whatever you want. I would probably have a UserAdmin class which has functions like deleteUser($userid) and editUser($userid) just because then its not confusing it with the auth side of things. However it can be done the other way. You could call a User object for a specific user and call deleteUser() on that to delete the user. Its what you feel most comfortable with.
As with all my answers, its what you want to do. There is no standard to this, and no rules. OOP is mainly about layering everything so that it makes sense, structurally, and about creating reusable code.
Another thing you want to look at is MVC programming. MVC stands for Model, View, Controller. In this set up you actually differentiate objects not by category (e.g. user, page etc) but by their function (e.g. model - connects to a database, view - has the code to layout a page, controller - computes stuff and passes data to the view). If you look at something like codeigniter then this will become more apparent to you.
Now you can create a model for users. In this model you can do all the database stuff, adding, editing, deleting users and such. This can then interface with a controller which will layout the page, e.g. seeing if the user is currently logged in, calling the user's model and getting the name of the user from the model, then passing it to the view to display on screen. This will make much more sense when you start using frameworks like code igniter.
Anyway, good luck in your learning.
It's really your own choice what is in a class and what is not. Mostly it's about what you find to create a good overview and what makes certain use-cases easier. In this case it will most likely cause more confusion if you split these operations, instead of putting them under the same banner.
I'd under most circumstances choose to put validation, signup, etc. in the same class. If admins are also users (and not a whole new table of users for example) I'd also include these in the same class - Or maybe create an admin class that extends the user class.
But there's no ultimate law of what is put in one class and what is not. It's about trial and error and seeing what gives you a good overview, and when you come to building abstraction layers, extending classes, etc. you need to be a little more careful. Taking the right steps can save you a ton of work in later work with extending classes.
I made the switch about 6 months ago from functional to OOP. I read a shitload of papers trying to figure out what the big deal about OOP is.
I think a conceptual understanding is important in this case. Think of an object as a physical thing.
A car:
A car has properties:
color
remaining petrol
top speed
A car has methods:
start
stop
accelerate.
1) A user is an object, login, logout, signup are actions/methods that a user does.
2) A user has session variables(properties) so I would place them as properties in the class
3) An admin user has more methods, but still needs acess to old ones. So idealy an admin user should inherit the properties and methods, I think this is done with the Extends keyword. This is called subclassing, or inhertance.
You best is to google "understanding oop concepts" and read whatever connects with you
I have 3 tables that contain user information, one for students, one for teachers and one for administrators.
They are not related in any way. I wan't to create a dashboard for the Administrators, where a list of students and teachers shows up.
The only way I found to achieve this was using the $uses variable in the Administrators controller. However, I have read in many places that this is bad practice.
Any solutions?
Another, perhaps better practice is the use of ClassRegistry::init('MyModel')->myMethod() (more reading # Cake API)
This only loads the object when it's used, as opposed to loadModel or uses, with ClassRegistry the models are treated as singletons.
--
that you are doing something wrong: you need access to a model that has nothing to do with your current controller.
There are plenty of conditions where you would need to access all of your models data, from one controller, but never a definitive answer on how to do it without breaking convention!
You can always use another Model which is not related by using
$this->loadModel('NewModelName');
Then you can access new loaded model by:
$this->NewModelName->add(); // whatever method model has defined
Why prefer loadModel() over uses?
To gain performance. How? uses calls the loadModel function itself to load all the models you specify in uses array. But the problem is if only one of your action needs a particular model, whats the good thing to include it in every action. e.g. only add() action requires an unrelated model, but if you have specified it in uses array, no matter what action gets called a completely unrelated model is going to load. To put simply it will be inefficient. Its like you have declared variables in a C programme but never used them. In case of C compiler will warn you that you are not using your variables, but unfortunately cake couldn't tell you.
Its alright to use uses if all your actions needs to load that model, use loadModel() otherwise.
You probably didn't read my answer in your other question :))
I have 3 tables that contain user information, one for students, one for teachers and one for administrators. They are not related in any way. I wan't to create a dashboard for the Administrators, where a list of students and teachers shows up.
The problem is you are separating similar data into 3 different tables, in this case, user information. So when you try to manage this data, you hit a brick wall: because you leave out the relationships when you separate them in 3 tables.
The only way I found to achieve this was using the $uses variable in the Administrators controller.
You got the wrong idea about the controller. Each controller manage the data flow of a particular model (and related models). It doesn't mean that you have to stay in Admin controller to do administrative things. What model you want to manipulate decides what controller you need to be in.
However, I have read in many places that this is bad practice.
Now for the main question: using $uses is a red flag that you are doing something wrong: you need access to a model that has nothing to do with your current controller. Now, there're always exceptions in programming, sometimes we need to have access to that model. That's where loadModel comes in. Because it should be rare. If you need the model a lot, then you'll need to call loadModel a lot, which is cumbersome, which is what $uses is for, but then that means something's wrong with your app design :))
So, you can say using $uses is a sign of bad decision (in DB design or application structure); and so is using loadModel a lot.
Edit: Any solutions?
I gave one solution in your other question. But if you want to have them all in one place, you can have 1 users table with user information. Each User can hasOne Student, Teacher, Administrator and a 'group' field to decide what group the User is. The third solution is using $uses. Its performance impact won't be a problem really. But it will be pretty convoluted when you develop your app further. That's what you need to worry about. For example, I can say that, if you use Auth, you'll need to tweak it a fair bit to get it working with 3 models. If you use the users table, it will be a lot easier.
i was just looking for a bit of advice, currently my DB design is that one user has many blog postings. Now i have a user class and a blog class.
However im not sure about the proper way to get all blog posts for that user. Do i create a getAllBlogs() function in the user class which returns blog objects or do i create a main blog class that you can search by user, so it'd be getAllBlogsForUser($id)
Thanks :-)
I'd personally use the later option. This is because the blog class knows how to deal with the blog table(s). I wouldn't want to write blog-specific DB code in the user class. On the other hand, you still can add User::getAllBlogs() as a wrapper around Blog::getAllBlogsForUser().
It's really up to you. Since users are pretty tightly coupled to blogs, you could do both.
Consider how nicely they could play together:
<?PHP
class User {
protected $_blogs;
public function getBlogs($force=false){
if (empty($this->_blogs) || $force){
$this->_blogs = BlogClass::getBlogsByUser($this->user_id);
}
return $this->_blogs;
}
}
Now you can grab a user's blogs whenever you want, and it will fetch them only when necessary. The $force parameter can be used to force a reload.
i am not sure if this is actually a helpful answer .. however if your db design is done correctly with the correct normalization practices in place .. it should be indicative of your class layouts as well. as User is an independent entity, and posts use user_id or something as the foreign key , it should clearly give you the idea who should be the master. Users can exist with-out posts , however posts can not exist with out users. So it makes sense to put the get posts method in the postings class rather than the users class.
I'd use both, like User::getPosts and Posts::findByUserId ("Posts" as model name sounds better to me than "Blogs" ). Both methods have similar functionality and which one to use depends on the context, for example, frontend will rather use Users model, while in admin interface 'finder' methods could be more appropriate.
I would create both. Your User::getBlogs() could use Blogs::getBlogsByUserId($idUser) since when you are in the user context, you will have access to the user's id to pass to the Blogs method.
This is my first foray into using an MVC construct (CodeIgniter). I'm hoping someone can tell me where the following elements belong. I have them written; I just want to make sure they're placed properly in their respective locations. This is how my application will run:
Call a DB and see if we have a user signed up
Route to a signup page
Route to the main preferences page for existing users
Make DB queries for producing a new user
Make update queries when users change their preferences
The service being provided is a cron job cycling every 10 minutes, which I still have written outside of CodeIgniter. Is this something I should/could add to the logic somewhere? It pings Twitter, and does stuff with any new tweets. Let me know if I can clarify any part of this!
Model
Controller
Controller
Model
Model
Rule of thumb: if it involves the database or the state of the application, it belongs in a model. If it is HTML or presentation logic, it belongs in a view. Controllers handle the rest of the logic, and help link the views and models together.
There are a lot of other things that come up too:
Where should I sanitise data? As it comes from the model - in the controller or finally before I view? I do it generally in the view if it's something like htmlspecialchars() (though I'm sure others might disagree).
Wikipedia has a very good article.