ZoneCMS: PDO / SECURE / MODERN [PlusEMU - FULL SUPPORT]

Status
Not open for further replies.

Zaka

Programmer
Feb 9, 2012
471
121
I was reading the last page of posts, and only saw @Sentinel providing an outdated template system (that would be limited, and not adapt well)

Apologies, just continue on and it's always best to code a higher-level function to handle something, then duplicating code
@Leader I appreciate your input tho, what you say is true, I just didn't want to complicate it that much. When I have a clearer picture of how it all works I'll make sure to update the thread with it.

@Sentinel no worries, it's alright, just keep it on topic.
 

BIOS

ಠ‿ಠ
Apr 25, 2012
906
247
Basically the same filter function, my classes are just structured another way, but this might give you an idea:
PHP:
use Acclimate\Container\CompositeContainer as Container;
class ContentController {

    protected $config, $page, $storage;

    protected static $html = [];

    public function setContainer(Container $container) {
        $this->config  = $container->get('Config');
        $this->page    = $container->get('PageController');
        $this->storage = $container->get('Storage');
    }

    protected function cache() {
        $page = $this->page;
        ob_start();

        $start = microtime(true);
        print("<!-- Licensed to https://nextzone.ga/u/Sentinel author of LucidCMS -->\r\n");

        if($page->current['header'] == 1) {
            include __DIR__ . "/../../html/header.html";
        }

        include __DIR__ . "/../../html/{$page->url}.html";

        if($page->current['footer'] == 1) {
            include __DIR__ . "/../../html/footer.html";
        }

        $end = microtime(true);
        printf("\r\n<!-- This page was rendered in %.6f seconds -->", ($end - $start));

        self::$html[$page->url] .= ob_get_contents(); //$this->page->filterParams();

        ob_end_clean();
    }

    public function output() {
        $this->cache();
        print($this->page->filterParams(self::$html[$this->page->url]));
    }

}
If it doesn't work, it might be because, I call all my functions on the page, after the system knows what page to show, so basically if I wanted it to filter all elements as we discussed, I just wrapped ob_get_contents() too with the filter function.
What's in PageController?

You should give full trust to the end-developer when developing systems.

Template Engines
That being said, when you code in features with user-interaction (Take a comment widget on the news for example), it's also important to provide a way to output that user data while filtering it. A really good example on handling template engines, while being secure and producing readable views is .

if you need any more ideas, it's also a good idea to code in view caching within your template engine to decrease the CPU load - and increase the out speed.

Other Things
If you're worried about exploits in general, you should code a database wrapper to handle any db queries you make - while adding in a function to automatically secure strings. This would also greatly benefit code readability.
Not necessarily, trust is something you need to watch.

For example, a front-end developer in the real world shouldn't be able to call back-end functions; this goes against the principle of least privilege since they do not require this. If a front-end developer is able to pass even a single back-end script to the server then you're doing it wrong.

I say this because in the real world of development, you'd typically have different front and back-end developers; the only thing the front should be able to access is any information which the back-end developer passes to the template.
 

MayoMayn

BestDev
Oct 18, 2016
1,423
683
What's in PageController?


Not necessarily, trust is something you need to watch.

For example, a front-end developer in the real world shouldn't be able to call back-end functions; this goes against the principle of least privilege since they do not require this. If a front-end developer is able to pass even a single back-end script to the server then you're doing it wrong.

I say this because in the real world of development, you'd typically have different front and back-end developers; the only thing the front should be able to access is any information which the back-end developer passes to the template.
Here you go:
PHP:
use Acclimate\Container\CompositeContainer as Container;
class PageController {

    /**
    * @var protected array
    */
    protected $params = [];
    /**
    * @var protected string
    */
    protected $db, $storage, $config, $user, $auth, $core, $uid, $container, $findretros, $session;
    /**
    * @var public string
    */
    public $url;
    /**
    * @var public array
    */
    public $current = [];

    /**
    * @return string
    */
    public function __construct() {
        $this->url = (!empty($_GET['url']) ? strtolower($_GET['url']) : "index");
    }

    /**
    * @return class
    */
    public function setContainer(Container $container) {
        $this->db       = $container->get('Database');
        $this->storage = $container->get('Storage');
        $this->config  = $container->get('Config');
        $this->user    = $container->get('UserController');
        $this->auth    = $container->get('AuthController');
        $this->core    = $container->get('Core');
        $this->findretros = $container->get('FindRetros');
        $this->session = $container->get('SessionController');
        $this->uid     = $this->session->get('user.id');
        $this->container = $container;
    }

    /**
    * @return current page string
    */ 
    public function handler() {
        $storage     = $this->storage;
        $config     = $this->config;
        $user         = $this->user;
        $core         = $this->core;
        $auth       = $this->auth;
        $online     = $auth->isLogged();
        //$rank       = $users->getInfo($this->uid, 'rank');
       

        if($config->hotel('ip_anon') == 1 || $core->validIP()) {
            if(file_exists(__DIR__ . "/../../html/" . $this->url . ".html") && $this->url != "error" && $this->url != "proxy") {
                if($online && $this->findretros->hasClientVoted() || empty($config->findretros('page'))) {
                    if(!$storage->get("page-" . $this->url)) {
                        $result = $this->db->prepare("
                            SELECT `title`,`session`,`disabled`,`min_rank`,`min_vip`,`header`,`footer` 
                                FROM `cms_pages` 
                            WHERE `name` = ? 
                                LIMIT 1
                        ")->execute([$this->url])->fetchAll();
           
                        $perms = [
                            'title'    => $result['title'],
                            'session'  => $result['session'],
                            'disabled' => $result['disabled'],
                            'min_rank' => $result['min_rank'],
                            'min_vip'  => $result['min_vip'],
                            'header'   => $result['header'],
                            'footer'   => $result['footer']
                        ];

                        $storage->set("page-" . $this->url, $perms);
                    }

                    $page = $storage->get("page-" . $this->url);
           
                    if($page['session'] == 0 && $online) {
                        header('Location: '.$config->hotel('url').'/home');
                        exit();
                    } elseif($page['session'] == 1 && !$online) {
                        $this->url = "error";
                    } elseif($page['disabled'] == 1) {
                        $this->url = "error";
                    } elseif($online) {
                        if($page['min_rank'] > $this->session->get('user.rank')) {
                            $this->url = "error";
                        } elseif($page['min_vip'] > $this->session->get('user.rank_vip')) {
                            $this->url = "error";
                        }
                    }

                    if($online && $this->url != "forum") {
                        if($user->isBanned($user->getUsername($this->uid)) || $user->isBanned($core->getIP())) {
                            $this->url = "banned";
                        }
                    }

                } else {
                    $this->findretros->redirectClientToVote();
                }
            } else {
                $this->url = "error";
            }
        } else {
            $this->url = "proxy";
        }

        $this->current = $storage->get("page-" . $this->url);

    }

    /**
    * @var array
    * @return void
    */
    public function setParams($params) {
        foreach($params as $key => $value) {
            $this->params[$key] = $value;
        }
    }

    /**
    * @var array
    * @return void
    */
    public function setFunctions($params = "") {
        if(!empty($params[$this->url])) {
            foreach($params[$this->url] as $class => $function) {
                call_user_func([$this->container->get($class), $function]);
            }
        }
    }

    /**
    * @return string
    */
    public function filterParams($str) {
       foreach($this->params as $key => $value) {
            $str = str_ireplace('{'.$key.'}', $value, $str);
        }

        return $str;
    }

}
 

BIOS

ಠ‿ಠ
Apr 25, 2012
906
247
Here you go:
PHP:
use Acclimate\Container\CompositeContainer as Container;
class PageController {

    /**
    * @var protected array
    */
    protected $params = [];
    /**
    * @var protected string
    */
    protected $db, $storage, $config, $user, $auth, $core, $uid, $container, $findretros, $session;
    /**
    * @var public string
    */
    public $url;
    /**
    * @var public array
    */
    public $current = [];

    /**
    * @return string
    */
    public function __construct() {
        $this->url = (!empty($_GET['url']) ? strtolower($_GET['url']) : "index");
    }

    /**
    * @return class
    */
    public function setContainer(Container $container) {
        $this->db       = $container->get('Database');
        $this->storage = $container->get('Storage');
        $this->config  = $container->get('Config');
        $this->user    = $container->get('UserController');
        $this->auth    = $container->get('AuthController');
        $this->core    = $container->get('Core');
        $this->findretros = $container->get('FindRetros');
        $this->session = $container->get('SessionController');
        $this->uid     = $this->session->get('user.id');
        $this->container = $container;
    }

    /**
    * @return current page string
    */
    public function handler() {
        $storage     = $this->storage;
        $config     = $this->config;
        $user         = $this->user;
        $core         = $this->core;
        $auth       = $this->auth;
        $online     = $auth->isLogged();
        //$rank       = $users->getInfo($this->uid, 'rank');
     

        if($config->hotel('ip_anon') == 1 || $core->validIP()) {
            if(file_exists(__DIR__ . "/../../html/" . $this->url . ".html") && $this->url != "error" && $this->url != "proxy") {
                if($online && $this->findretros->hasClientVoted() || empty($config->findretros('page'))) {
                    if(!$storage->get("page-" . $this->url)) {
                        $result = $this->db->prepare("
                            SELECT `title`,`session`,`disabled`,`min_rank`,`min_vip`,`header`,`footer`
                                FROM `cms_pages`
                            WHERE `name` = ?
                                LIMIT 1
                        ")->execute([$this->url])->fetchAll();
         
                        $perms = [
                            'title'    => $result['title'],
                            'session'  => $result['session'],
                            'disabled' => $result['disabled'],
                            'min_rank' => $result['min_rank'],
                            'min_vip'  => $result['min_vip'],
                            'header'   => $result['header'],
                            'footer'   => $result['footer']
                        ];

                        $storage->set("page-" . $this->url, $perms);
                    }

                    $page = $storage->get("page-" . $this->url);
         
                    if($page['session'] == 0 && $online) {
                        header('Location: '.$config->hotel('url').'/home');
                        exit();
                    } elseif($page['session'] == 1 && !$online) {
                        $this->url = "error";
                    } elseif($page['disabled'] == 1) {
                        $this->url = "error";
                    } elseif($online) {
                        if($page['min_rank'] > $this->session->get('user.rank')) {
                            $this->url = "error";
                        } elseif($page['min_vip'] > $this->session->get('user.rank_vip')) {
                            $this->url = "error";
                        }
                    }

                    if($online && $this->url != "forum") {
                        if($user->isBanned($user->getUsername($this->uid)) || $user->isBanned($core->getIP())) {
                            $this->url = "banned";
                        }
                    }

                } else {
                    $this->findretros->redirectClientToVote();
                }
            } else {
                $this->url = "error";
            }
        } else {
            $this->url = "proxy";
        }

        $this->current = $storage->get("page-" . $this->url);

    }

    /**
    * @var array
    * @return void
    */
    public function setParams($params) {
        foreach($params as $key => $value) {
            $this->params[$key] = $value;
        }
    }

    /**
    * @var array
    * @return void
    */
    public function setFunctions($params = "") {
        if(!empty($params[$this->url])) {
            foreach($params[$this->url] as $class => $function) {
                call_user_func([$this->container->get($class), $function]);
            }
        }
    }

    /**
    * @return string
    */
    public function filterParams($str) {
       foreach($this->params as $key => $value) {
            $str = str_ireplace('{'.$key.'}', $value, $str);
        }

        return $str;
    }

}

PageController:
PHP:
    public function __construct() {
        $this->url = (!empty($_GET['url']) ? strtolower($_GET['url']) : "index");
    }


Might want to watch the page URL in your ContentController class:
PHP:
include __DIR__ . "/../../html/{$page->url}.html";

No checks are made to ensure the file exists, this could potentially leave you vulnerable to LFI.
 

Liam

trust nobody
Staff member
FindRetros Moderator
Apr 10, 2013
1,184
713
Looks alright. I don't like the orange, unless you're allowing users to change the colours via account settings or something. Me page and profiles could do with a bit more detail to them, maybe add avatars to the guestbook comments. Logo looks too far away, it wouldn't look bad on small screens but on big screens it looks weird. Housekeeping looks cool, has everything you'd usually need. Good luck :)
 

Zaka

Programmer
Feb 9, 2012
471
121
Looks alright. I don't like the orange, unless you're allowing users to change the colours via account settings or something. Me page and profiles could do with a bit more detail to them, maybe add avatars to the guestbook comments. Logo looks too far away, it wouldn't look bad on small screens but on big screens it looks weird. Housekeeping looks cool, has everything you'd usually need. Good luck :)
Thx for the feedback, I haven't actually updated the main post with the new changes because they come along in the thread. But the comment about the logo and the colours have been fixed, although I'm working on a new design that is fully responsive and all, so hopefully it will be all good! :)
 

Menkz

Member
Jul 9, 2010
374
167
This has potential - a template system would be amazing to grow the CMS and have community input towards it.

Looks alright. I don't like the orange, unless you're allowing users to change the colours via account settings or something. Me page and profiles could do with a bit more detail to them, maybe add avatars to the guestbook comments. Logo looks too far away, it wouldn't look bad on small screens but on big screens it looks weird. Housekeeping looks cool, has everything you'd usually need. Good luck :)

Ya, the front-end of the CMS looks a little tacky and ugly ~ although it's unique.
 

Zaka

Programmer
Feb 9, 2012
471
121
This has potential - a template system would be amazing to grow the CMS and have community input towards it.



Ya, the front-end of the CMS looks a little tacky and ugly ~ although it's unique.
The "template" system that is being implemented is not necessarily following the template standards, and therefore I don't really call it a template system, but I'm making it easy to change structures within diffrerent "themes". This process, to create new themes wont be 100% noob friendly since I won't be using clean HTML in the template files. But the rest of the cms will be super easy. This has it's pros and cons.

Pros: Developers can easily create a theme without the need to really mix with the core classes and such to implement new parameters.
Cons: It's a bit harder to actually create themes since it's PHP and HTML combined.
 

Menkz

Member
Jul 9, 2010
374
167
The "template" system that is being implemented is not necessarily following the template standards, and therefore I don't really call it a template system, but I'm making it easy to change structures within diffrerent "themes". This process, to create new themes wont be 100% noob friendly since I won't be using clean HTML in the template files. But the rest of the cms will be super easy. This has it's pros and cons.

Pros: Developers can easily create a theme without the need to really mix with the core classes and such to implement new parameters.
Cons: It's a bit harder to actually create themes since it's PHP and HTML combined.
Ah, I see, didn't really READ the thread, more skimmed through it.
It shouldn't be too hard to create templates if you know basic html, css and php.
 

Zaka

Programmer
Feb 9, 2012
471
121
Ah, I see, didn't really READ the thread, more skimmed through it.
It shouldn't be too hard to create templates if you know basic html, css and php.
Yeah, I mean, I could do it so that only HTML is written in the HTML files and that every piece of data needs to be set using presets, but I didn't wanna do it that way because it just complicates stuff, instead it's more of a mix, you can use parameters and raw php aswell

[UPDATE 2017-02-19 07:38]
I've started to re-design some parts of the cms and make it all responsive, although it seems I just can't find a design on the index that I like too much... I need your help guys! This is what I have for the index so far:
fadef4b4ff42414bb1860e93638ee1e6.png

3bc47ecba2b043b5bf164c93073ee1b0.png
 
[UPDATE 2017-03-03 05:00 GMT +1]
I've re-designed a big part of the cms and I'm making it responsive. Mostly have been visual and I haven't really worked with the cms so much these past days because I've been working a lot, but I'm back at it and this is what I've got for now!
6e6da01a481843edab31052993759d0e.png

4111648e526a43dc9e653bddfa7114d3.png
 

Seriosk

Programmer;
Oct 29, 2016
256
105
There are certain pagThere are certain pages and ideas of this project that really grabs my attention, but then there are parts that just make me want to not use it, but it does look unique, any news on this?es and ideas of this project that really grabs my attention, but then there are parts that just make me want to not use it. Anyway, good luck as it does look decently good so far. Above noob level.
 

Zaka

Programmer
Feb 9, 2012
471
121
There are certain pagThere are certain pages and ideas of this project that really grabs my attention, but then there are parts that just make me want to not use it, but it does look unique, any news on this?es and ideas of this project that really grabs my attention, but then there are parts that just make me want to not use it. Anyway, good luck as it does look decently good so far. Above noob level.
I would really like for you to tell me what parts so I can look at them. I'm currently re-designing the whole cms since the design presented in the main post isn't that good.
 

Weasel

👄 I'd intercept me
Nov 25, 2011
4,132
2,456
Looking at the snippets in your OP, you should really clean up the style of your code a bit. Sometimes you use brackets, sometime's you don't - etc. Also, you can simplify some of the code.

For example, this:
PHP:
if( isset($_SESSION[$key]) )
    return true;
else
    return false

Can be done like this
PHP:
return isset($_SESSION[$key]);

Tada.
 

Zaka

Programmer
Feb 9, 2012
471
121
Looking at the snippets in your OP, you should really clean up the style of your code a bit. Sometimes you use brackets, sometime's you don't - etc. Also, you can simplify some of the code.

For example, this:
PHP:
if( isset($_SESSION[$key]) )
    return true;
else
    return false

Can be done like this
PHP:
return isset($_SESSION[$key]);

Tada.
I have a list of things that I'm gonna go through, and one of these are just that, I haven't really been consistent, and this is due to me working on this cms for such a long period of time, on and off, this cms has had 3 really extensive changes overall. But I decided that when I'm done with all the work like re-designing and getting everything to work as should, then as a last touch I will go through all code and organize it more properly! :) But thanks for pointing it out!

Also, made some changes to the earlier shown design, more specifically stayed with one colour for the headers + moved in the menu and logo + icons. Looks much better now imo
a347d17b8a9746b9bca9d4c7d3048db7.png
 

Weasel

👄 I'd intercept me
Nov 25, 2011
4,132
2,456
I have a list of things that I'm gonna go through, and one of these are just that, I haven't really been consistent, and this is due to me working on this cms for such a long period of time, on and off, this cms has had 3 really extensive changes overall. But I decided that when I'm done with all the work like re-designing and getting everything to work as should, then as a last touch I will go through all code and organize it more properly! :) But thanks for pointing it out!

Also, made some changes to the earlier shown design, more specifically stayed with one colour for the headers + moved in the menu and logo + icons. Looks much better now imo
-- snip --/QUOTE]

The design looks better, but everything seems rather big and not really "modern".
 

Zaka

Programmer
Feb 9, 2012
471
121
Modern or not, I need to keep it "habboish" to a certain level, if I could design it with a modern design I would rather do that, it's been really hard for me to try to design "for habbo". But this will be the default theme that comes with the cms, if someone wants to create a new theme they can do that, it is supported! :p
 
Status
Not open for further replies.

Users who are viewing this thread

Top