userfrosting / UserFrosting

Modern PHP user login and management framework
https://www.userfrosting.com
Other
1.63k stars 366 forks source link

MVC version of UF? #130

Closed alexweissman closed 9 years ago

alexweissman commented 10 years ago

Up until now, I've been worried about adopting a formal MVC structure for UF because it tends to reek of a Big Framework. However, I'm considering a way to adopt MVC without turning this into a framework. What do you guys think of this project: https://github.com/panique/php-mvc ?

lilfade commented 10 years ago

Yea i seen the comments on the post, thought of this project or just starting from scratch either way its going to turn into a lot of work and is going to be a framework eventually no matter what once we go this route. But i think we can do it and still make it extremely user friendly and easy to config and setup in the long run as it is now.

On the plus side we have file orignazation system now unlike back in 0.1.0 where it was just freaking crazy. I think if we do this we might as well create / convert to a orm system to make alot less code. I like the idea of rolling our own orm but we have to keep it simple for the user to understand as well.

r3wt commented 10 years ago

since UF is supposed to be a Web2.0 project ,why not go for the MOVE design pattern? MOVE takes the best of MVC and slaps it together with the DRY pattern, and the data component is completely absent from the design. you bind your event logic to the view (in the form of javascript that will execute ajax to retrieve the data object for your view)

here's an example of a move project i'm building in slim php

$app->get('/cart',function() use($base,$app,$uploads){

    //MOVE is polymorphic. you can choose to bind your data model to the view from inside the controller, or instead bind an ajax event to fetch it in a true MOVEly manner. 
    $seo = 'keywords';
    $title = 'title';
    $desc = 'description';
    $img   = '/assets/img/logo2.png';
    $url   = $app->request()->getPath();
    $content = 'cart.html';
    $template = 'template.html';
    $html = new \r3wt\View($template,$content,$title,$desc,$base,$seo,$img,$url);

    echo $html->compile()->render();

});

you can build yet another clunky slow MVC or you can get ahead of the curve and join the MOVE train. if you want tradition MVC, do angular.js instead of php. just my two cents i may decide to contribute again some day.I'd also be up for replacing bootstrap with foundation, but i'm probably alone in that.

heres what my single controller looks like. as you can see you have only one controller in a move project, since all data is handled via ajax requests. no more clunkly logic inside of your view controller! yippee

namespace r3wt;
class View{
    private $template;
    private $search;
    private $replace;
    public $html;

    function __construct($template_name,$content_name,$title,$description,$base,$seo,$image,$url,$extra_search = false,$extra_replace = false){
        if(!file_exists(__DIR__ . '/../../' . DIRECTORY_SEPARATOR .'views'. DIRECTORY_SEPARATOR . security2($template_name))){
            throw new \Exception('invalid template file');
        }
        if(!file_exists(__DIR__ . '/../../' . DIRECTORY_SEPARATOR .'views'. DIRECTORY_SEPARATOR . security2($content_name))){
            throw new \Exception('invalid content file');
        }
        $this->template = file_get_contents(__DIR__ . '/../../' . DIRECTORY_SEPARATOR .'views'. DIRECTORY_SEPARATOR . security2($template_name));
        $content  = file_get_contents(__DIR__ . '/../../' . DIRECTORY_SEPARATOR .'views'. DIRECTORY_SEPARATOR . security2($content_name));
        $this->search  = ['#CONTENT#','#BASE#','#SEO#','#TITLE#','#IMG#','#DESC#','#URL#',];
        $this->replace = [$content,$base,$seo,$title,$base.$image,$description,$base.$url];

        //views can add extra search/replace content
        if($extra_search && $extra_replace){
            if(is_array($extra_search) && is_array($extra_replace)){
                $this->search  = array_merge($this->search,$extra_search);
                $this->replace = array_merge($this->replace,$extra_replace);
            }
        }
    }

    public function compile(){
        $this->html = str_replace($this->search,$this->replace,$this->template);
        return $this;
    }

    public function render(){
        return $this->html;
    }
}
lilfade commented 10 years ago

holy crap ^ this guy comes back from the dead >_>

r3wt commented 10 years ago

@lilfade lol, just leveling up. working 24/7 lol. looking for a open source project to join up. i seriously have hundreds of namespaced classes like this. everything from paypal payment processors to email classes, data objects, cache writers, rest data modeler etc.

lilfade commented 10 years ago

Is there any documentation on the Move design pattern such as examples of using it besides the 2 blog posts i found about it i cant find anything else, i guess its really up to @alexweissman i mean in the long run we could even make our own framework if we dont go the mvc route (which i do like but there always seems to be a learning curve for most frameworks) at this point we have a fully working system just need to nail down the future design pattern and we should be set.

lilfade commented 10 years ago

I did find these for event systems, i mean how hard would it be to roll our own framework with all the systems we currently have to use we have authencation as well as a page manager (sort of).

https://github.com/mapkyca/simple-event-dispatcher https://github.com/WouterJ/shift-php

alexweissman commented 10 years ago

Well, it's up to all of us. This is an open source project, after all ;-)

MOVE sounds promising. I feel like we're doing a lot of this already, we just haven't formalized it. I also like how it seems to be oriented towards push/pull applications, which are becoming in vogue.

Honestly, I'm not obsessing over strictly implementing one of these design paradigms. I just want to make UF easier to develop, extend, and maintain, while keeping it functional out-of-the-box and easy for beginner programmers to work with.

Also, welcome back @r3wt!

r3wt commented 10 years ago

@alexweissman i agree with you completely. There should be no need to nail UF down to one design pattern. we could go to the drawing board here and come up with an awesome and easily extensible system in our own hybrid design pattern. MVC would be hard for many beginners i think. a loosely coupled move app like what i've proposed is really easy to build on. adding a new view is as simple as adding a new route to index.php and then building the html template and binding your data model(either through ajax or directly in the route callback.) i'm up to sit back and take instructions but if i had the say i would go this way because its the way i like it. loosely coupled, flexible and easily extended.

lilfade commented 10 years ago

So pretty much were just going to let it evolve on its own then?, that's cool. So i guess the big thing is still the ORM to make everything easier and cut down on some code then.

alexweissman commented 10 years ago

Well, I'd like to focus on introducing more structure (like an ORM). But also, defining and separating the layers that data passes through more clearly.

There is still a ton of redundant/spaghetti code that could benefit from abstraction. For example, the validation system that I've started working on in bootsole should be finished and then dropped into UF. Also, I've devised a system for managing CSS/JS dependencies.

I also want to fix the way we are handling function authorization right now. We have to write a separate authorization function for every data function, at the moment. I'd rather just have some kind of interface that allows us to call the exact same function, but either in "secure" mode or "direct" mode.

It looks like I'm going to be pretty busy for the rest of the semester, unfortunately. So, it might not be until December when I have a chance to work on these things some more :(

muhzak commented 9 years ago

I think this is a great idea. I grabbed your code for a project of mine and first thing I did was try to start using it as model view controller for anything new I wrote.

Treat everything as a plugin. Inside that I have models, controller, api folder.

Views for all the plugins are together for now, but they should be in their respective folders. I also used an old templating engine (smarty) because I wanted to borrow some of my old code to get stuff out fast.

But there is a some good work here. You should all be proud. I'm very busy right now with work also levelling up. But if I can I will try to contribute over winter break.

lilfade commented 9 years ago

Well looking at it last night I noticed most of UF was set into a sort of mvc loosely already. Besides introducing a templating engine it's pretty good as it is now, I think we should just let it evolve as we go along like we have been doing this whole time. If people write plugins to conform to some type of standard that's fine but I don't think we need to change much in our structure anyways.

On Thu, Nov 6, 2014, 10:22 AM muhzak notifications@github.com wrote:

I think this is a great idea. I grabbed your code for a project of mine and first thing I did was try to start using it as model view controller for anything new I wrote.

Treat everything as a plugin. Inside that I have models, controller, api folder.

Views for all the plugins are together for now, but they should be in their respective folders. I also used an old templating engine (smarty) because I wanted to borrow some of my old code to get stuff out fast.

But there is a some good work here. You should all be proud. I'm very busy right now with work also levelling up. But if I can I will try to contribute over winter break.

Reply to this email directly or view it on GitHub https://github.com/alexweissman/UserFrosting/issues/130#issuecomment-62004941 .

alexweissman commented 9 years ago

Something I am starting to change my tune on, which lines up with MVC, is the notion of URL routing. Originally, I liked having a literal mapping of individual PHP files to URLs. But, now I'm starting to gain an appreciation for decoupling the URLs from the actual files.

For example, it would be so elegant to have urls like:

http://zergdate.com/users/create/,
http://zergdate.com/users/list/,
http://zergdate.com/users/u/alexweissman/

A simple controller class could intercept and parse these URLs, and then render the appropriate content. Thoughts?

lilfade commented 9 years ago

I'm always game to have a "controller" for our classes, although most of out /account/ pages are pretty much a controller as it stands now so it shouldn't be to much to get those changed over to have pretty url's ^_^

alexweissman commented 9 years ago

We could use a prebuilt routing engine like Klein. I agree, account and api pages already function as controllers but it would be good if we could make them more modular and reduce the redundant code.

Plus, I am starting to notice a lot of scenarios where I don't necessarily want an actual, separate PHP file for every URL.

For example, my practice exam system: https://bloomingtontutors.com/quiz/finite-math. Different practice problems for every course, but there are potentially dozens of different courses, and they all fetch problems from the DB in exactly the same way.

alexweissman commented 9 years ago

Old-ass thread - this really takes me back! I've learned so much since.