[PHP, MySQLi] leHabbo

Status
Not open for further replies.

Synt4x

Member
Jan 13, 2016
77
59
Hi everybody,

I am excited to announce the close arrival of leHabbo. Prepare yourself, because this next statement is going to be bold: the next biggest CMS to RevCMS, PHPRetro and HoloCMS. On what grounds can I make such a bold claim? Well you see, this CMS has been designed to be lightweight and flexible as possible making things as easy as they was with the above CMS'. Did I mention it's packed full of features?

Okay, so you say it's good - but what features does it have?
  • Themes - while everybody knows that this has become a necessity of Habbo CMS' nowadays, it's still a good feature to have. In leHabbo, themes can even control routing, meaning that there's no more ugly .htaccess or web.config.
  • VC - what does this even mean? Well, I have been using MVC structures for years in my applications, and making a CMS wouldn't feel the same without one. Thus, I decided to keep things fairly basic and just adopt the "VC" (view, controller) approach. This would force new developers to get out of bad habits and stop mixing raw mysql with html. It's just not cool.
  • Avatar Building - thanks to Xenon (iExit) for releasing the javascript avatar builder. I implemented this feature into leHabbo upon registering.
  • Full housekeeping - the way things should be. With full user management, site management (news articles, swf management - change swf links, etc), staff management. Anybody got any other ideas? You're also able to change your housekeeping directory by just defining it within the config file. It'll automatically update all the files and URLs :)
  • SQL & CSRF attack prevention - Fairly standard way of coding nowadays. All SQL statements are prepared and thus are not subject to injection. CSRF attacks are also prevented in a similar way to how Laravel does things. (Injects a unique code into the form and then checks the users session for that very same code.)
  • Custom design - most things have been designed from scratch (based upon the current Habbo website). I have tried to make the default theme as consistent as possible. When the theme is released, the whole PSD will be available for those that wish to change things.
  • Full Documentation - because this is a community release, and I wish to give back to the same community that helped me to develop my career in coding, I would like to reciprocate by giving full documentation to help those understand the classes that are available within the CMS and how to utilise them.
Routing Class:
PHP:
<?php
/*
* leHabbo is a free Habbo Content Management System and
* should be used to replicate the Habbo website for educational
* purposes only. Under no circumstances should leHabbo be used
* to generate income for their respective owner(s) or other
* parties.
*
* It was a project created in order to give back to the
* Habbo community after years of a halt of development.
* The project was created by instaIsolated.
*
* @path    Habbo/Core/routing/Route.php
*/

namespace leHabbo\Routing;

if( ! defined( 'LEHABBO' ) ) die( 'Direct access prohibited.' );

class Route
{

    /*
     * All routes to be held
     *
     * @type        array<string>
     * @visibility  public static
     */

    public static $routes = array();


    /*
     * All custom paths
     *
     * @type        array<string>
     * @visibility  public static
     */

    public static $paths = array();


    /*
     * Stoppage if match is found
     *
     * @type        boolean
     * @visibility  public static
     */

    public static $halts = false;


    /*
     * All methods to be held
     *
     * @type        array<callback>|string
     * @visibility  public static
     */

    public static $methods = array();


    /*
     * All HTTP methods we will use
     *
     * @type        array<string>
     * @visibility  public static
     */

    public static $httpMethods = array();


    /*
     * Hold the error method, in case the route
     * is not found.
     *
     * @type        callback
     * @visibility  public static
     */

    public static $errorMethod;


    /*
     * The folder name for Housekeeping
     *
     * @type        callback
     * @visibility  public static
     */

    public static $housekeeping = 'housekeeping';


    /*
     * Stack all of our methods, URIs and HTTP methods
     *
     * @param string   $httpMethod
     * @param array    $parameters
     */

    public static function __callStatic( $httpMethod, $parameters )
    {
        /*
         * Start stacking our methods and routes to our stacks
         */

        array_push( self::$methods, $parameters[1] );
        array_push( self::$httpMethods, strtoupper( $httpMethod ) );

        array_push( self::$paths, ( isset( $parameters[2] ) ) ? $parameters[2] : "" );
        array_push( self::$routes, '/' . $parameters[0] );

    }


    /*
     * Run the error method in case we find no matching
     * routes.
     *
     * @param callback $method
     */

    public static function error( $method = NULL )
    {
        self::$errorMethod = $method;
    }


    /*
     * Let's dispatch the route if there's a match,
     * and if not let's throw the error page at them.
     */

    public function dispatch()
    {
        global $error, $config, $URL;

        $URI = '/' . trim( parse_url( $_SERVER['QUERY_STRING'], PHP_URL_PATH ), '/' );

        $httpMethod = $_SERVER['REQUEST_METHOD'];

        /*
         * Check if the URI is contained within the route
         * without using regex
         */

        if ( in_array( $URI, self::$routes ) ) {
            /*
             * Check if our URL has a match with our routes
             * and if so, pull the array index
             */

            $routes = ( ! empty( array_keys( self::$routes, $URI ) ) ) ? array_keys( self::$routes, $URI ) : NULL;

            if ( $routes !== NULL ) {
                /*
                 * Run a foreach loop in case we have more than
                 * one match - we want to use the first one.
                 */

                foreach ( $routes as $route ) {
                    /*
                     * Check if our http request is the same as stated
                     * within the route. i.e. Route::get, Route::post
                     * or matches any.
                     */

                    if ( self::$httpMethods[ $route ] == $httpMethod || self::$httpMethods[ $route ] == 'ANY' )
                    {
                        /*
                         * If the method supplied is callable, then let's
                         * run it, otherwise build the page specified,
                         * if a valid page.
                         */

                        if ( is_object( self::$methods[ $route ] ) )
                            call_user_func( self::$methods[ $route ] );
                        else
                        {
                            $nroute = self::$methods[ $route ];
                            $nroute = explode( '@', $nroute );


                            if( strpos( self::$routes[ $route ], $config['site']['hk_name'] ) !== false )
                            {
                                $fullFile = BASE . 'housekeeping/controllers' . DIRECTORY_SEPARATOR . $nroute[0] . '.php';
                            }
                            else
                            {
                                if( self::$paths[ $route ] != "" )
                                {
                                    $fullFile = ltrim( self::$paths[ $route ], '/' ) . '/' . $nroute[0] . '.php';
                                }
                                else
                                {
                                    $fullFile = $URL->controllerPath() . $nroute[0] . '.php';
                                }
                            }

                            if ( ! file_exists( $fullFile ) )
                            {
                                $error->__404( $fullFile );
                            }
                            else
                            {
                                require_once( $fullFile );

                                $className = ucfirst( $nroute[0] );
                                $class = new $className();
                                $method = $nroute[1];

                                if( isset( $method ) )
                                {
                                    if( method_exists( $class, $method ) )
                                        $class->$method();
                                    else
                                        die( $method . ' method is missing from controller' );
                                }
                                else
                                {
                                    die( 'Index method is missing from your controller as default and no other method was given. ');
                                }
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if ( is_callable( self::$errorMethod ) )
                call_user_func( self::$errorMethod );
            else
                exit( $error->prettyError( 'Oops!', 'The page you was looking for does not exist' ) );
        }
    }
}
Login Controller
PHP:
<?php if( ! defined( 'LEHABBO' ) ) die( 'Direct access prohibited.' );
/*
* leHabbo is a free Habbo Content Management System and
* should be used to replicate the Habbo website for educational
* purposes only. Under no circumstances should leHabbo be used
* to generate income for their respective owner(s) or other
* parties.
*
* It was a project created in order to give back to the
* Habbo community after years of a halt of development.
* The project was created by instaIsolated.
*
* @path Habbo/themes/Habbo/controllers/login.php
*/

use \leHabbo\Misc\Controller as Controller;

class Login extends Controller
{

    public function index()
    {
        if( ! $this->habbo->isLoggedIn() )
        {
            $this->view->load( $this->URL->viewPath( 'index.php' ) );
            $this->view->footer( $this->URL->viewPath( '/templates/footer.php' ) );

            /*
             * Select 1 news article
             */

            $article = $this->db->getOne('cms_news');

            $this->view->set('errors', $this->session->getFlashData('errors'));
            $this->view->set('csrf_token', $this->session->generateCsrfToken());

            $this->view->set('newsArticle', $article['title']);
            $this->view->set('newsCaption', $article['shortstory']);
            $this->view->set('newsDate', 'Today @ 9pm');
            $this->view->set('newsCategory', 'Campaigns & Activities');
            $this->view->render();
        }
        else
        {
            $this->URL->redirect( $this->URL->base( 'me' ) );
        }
    }

    public function post()
    {
        if( ! $this->habbo->isLoggedIn() )
        {
            if( ! $this->habbo->isBanned( $this->habbo->getIP() ) )
            {
                if( $this->session->validateCsrfToken( $_POST['csrf_token'] ) )
                {
                    if( $this->habbo->checkUserAuth( $_POST['habbo-l-name'], $_POST['habbo-l-password'] ) )
                    {
                        $this->habbo->updateUser( 'ip_last', $this->habbo->getIP(), 12 );
                        $this->URL->redirect( $this->URL->base( 'me' ) );
                    }
                    else
                    {
                        $this->session->setFlashData( 'errors', 'Your username or password was incorrect.' );
                        $this->URL->redirect( $this->URL->base() );
                    }
                }
                else
                {
                    $this->session->setFlashData( 'errors', 'Session-jacking detected.' );
                    $this->URL->redirect( $this->URL->base() );
                }
            }
            else
            {
                $this->session->setFlashData( 'errors', 'You have been banned from the hotel.' );
                $this->URL->redirect( $this->URL->base() );
            }
        }
        else
        {
            $this->URL->redirect( $this->URL->base( 'me' ) );
        }
    }

}

Avatar Controller
PHP:
<?php if( ! defined( 'LEHABBO' ) ) die( 'Direct access prohibited.' );
/*
* leHabbo is a free Habbo Content Management System and
* should be used to replicate the Habbo website for educational
* purposes only. Under no circumstances should leHabbo be used
* to generate income for their respective owner(s) or other
* parties.
*
* It was a project created in order to give back to the
* Habbo community after years of a halt of development.
* The project was created by instaIsolated.
*
* @path Habbo/themes/Habbo/controllers/avatar.php
*/

use \leHabbo\Misc\Controller as Controller;

class Avatar extends Controller
{

    public function index()
    {
        if( $this->habbo->isLoggedIn() )
        {
            $this->view->load(BASE . SKINS . 'Habbo/views/register/avatar.php');
            $this->view->footer(BASE . SKINS . 'Habbo/views/templates/footer.php');

            $this->view->set('enteredUsername', ($this->session->getFlashData('enteredUsername') != NULL) ? $this->session->getFlashData('enteredUsername') : '');
            $this->view->set('enteredEmail', ($this->session->getFlashData('enteredEmail') != NULL) ? $this->session->getFlashData('enteredEmail') : '');
            $this->view->set('errors', $this->session->getFlashData('errors'));
            $this->view->set('csrf_token', $this->session->generateCsrfToken());

            $this->view->render();
        }
        else
        {
            $this->URL->redirect( $this->URL->base() );
        }
    }


    public function save()
    {
        if( $this->habbo->isLoggedIn() )
        {
            $this->habbo->updateUser( 'look', $this->input->cleanString( $_POST['habbo-look'] ), $this->session->get( 'habboID' ) );
            $this->URL->redirect( $this->URL->base( 'me' ) );
        }
        else
        {
            $this->URL->redirect( $this->URL->base() );
        }
    }


}

Example of a routing file:
PHP:
<?php if( ! defined( 'LEHABBO' ) ) die( 'Direct access prohibited.' );
/*
* leHabbo is a free Habbo Content Management System and
* should be used to replicate the Habbo website for educational
* purposes only. Under no circumstances should leHabbo be used
* to generate income for their respective owner(s) or other
* parties.
*
* It was a project created in order to give back to the
* Habbo community after years of a halt of development.
* The project was created by instaIsolated.
*
* @path Habbo/Routes/leHabbo.php
*/

use \leHabbo\Routing\Route as Route;


/*
* Begin our main routes
*/

Route::get( '', 'login@index' );
Route::post( '', 'login@post' );

Route::get( 'index', 'index@index' );
Route::post( 'index', 'index@post' );

Route::get( 'register', 'register@index' );
Route::post( 'register', 'register@save' );

Route::get( 'avatar', 'avatar@index' );
Route::post( 'avatar', 'avatar@save' );


/*
* Define our error method incase all
* should fail.
*/

Route::error( function() {
    echo 'Error 404';
});

There are far more files, but I thought I'd include one or two just so you can get a feel for how the CMS works.

o3dGtPY.png
wMtlgpR.png
860GYmJ.png
Prs4umA.png
3rV9WHZ.png
BcVe4hA.png
gi0HQkY.png

I hope that you're all looking forward to the release of the CMS and will continue to support it. The final release should be available by 21st March 2016. Also, please understand that the above screenshots are NOT the finished product, and you will see moderate changes between now and the release date.

YOU CAN FIND A LIVE DEMO OF LEHABBO AT:

Credits:
Xenon (Avatar)
Myself (Design and coding)
 
Last edited:
R

Referee

Guest
That looks very nice- Will be great to keep up with it's development. Goodluck :)
 

LeChris

github.com/habbo-hotel
Sep 30, 2013
2,744
1,326
The primary thing I'm looking forward to is this design, which if I must say is quite phenomenal
 

Synt4x

Member
Jan 13, 2016
77
59
Thank you - the design was a very hit or miss thing in my mind, but I'm glad that it's okay! Cheers for the feedback.
 

BIOS

ಠ‿ಠ
Apr 25, 2012
906
247
XSS is also prevented in a similar way to how Laravel does things. (Injects a unique code into the form and then checks the users session for that very same code.)
You're refering to CSRF here, not XSS i'm presuming?

Doesn't look too bad from the provided snippets, seen a few developments follow similar approaches, could still use some more work though

Design wise, there's currently not too much to look at from what you've provided apart from a few features of the HK, share more screenshots if possible?
 

Synt4x

Member
Jan 13, 2016
77
59
You're refering to CSRF here, not XSS i'm presuming?

Doesn't look too bad from the provided snippets, seen a few developments follow similar approaches, could still use some more work though

Design wise, there's currently not too much to look at from what you've provided apart from a few features of the HK, share more screenshots if possible?
Correct, yes. I should update that.
You say it could still use some more work though, but what would you suggest? And that's all I'm at with the design stage at the moment, the rest is still in process. Thanks for the comment :)
 

Rain

c
Mar 13, 2015
558
243
I like this a lot, looks tidy asf. Good documentation.
Looking forward to the release :)
 

Synt4x

Member
Jan 13, 2016
77
59
I like this a lot, looks tidy asf. Good documentation.
Looking forward to the release :)
Thanks man! Currently working on a default a CLEAN Habbo theme too for those that wish to not have the above. The housekeeping will remain the same though.

Which brings to another point: themes also have the ability to override the housekeeping styling.
 

griimnak

You're a slave to the money then you die
Jul 20, 2013
956
797
Goodluck, the code looks relatively clean and the theme looks okay
That hk dash needs some more content however.
TKJSxIy.png
 
  • Like
Reactions: Zac

Synt4x

Member
Jan 13, 2016
77
59
Hahah, hey man :D
This is really good. Good luck!
Thank you!
Goodluck, the code looks relatively clean and the theme looks okay
That hk dash needs some more content however.
TKJSxIy.png
Thanks for the feedback, but for sure - this is definitely not a finished product and I just wanted to get something up for the dashboard (by no means have I finished any of the design yet).
 

Ork

New Member
Dec 29, 2010
29
1
Looks great so far. I'm sure you are planning on this but if you could maybe add News Article editors to the HK and I'd also really like to see a simple to use catalog editor :)

Other than that I'm looking forward to release! Any more progress on this?
 

Synt4x

Member
Jan 13, 2016
77
59
Looks great so far. I'm sure you are planning on this but if you could maybe add News Article editors to the HK and I'd also really like to see a simple to use catalog editor :)

Other than that I'm looking forward to release! Any more progress on this?

Those things will definitely be on there, the housekeeping panel is going to be very detailed. There has indeed been progress on this, but nothing that I can visually show you - I have changed the file structure to make things neater and removed the use of static classes. The code now uses a service container to handle all instance of classes and is much more heavily reliant on Dependency Injection (sticking to best practices) due to there going to be a lot of updates in the future.
 

Ork

New Member
Dec 29, 2010
29
1
Alright thank you for the update. If you would like a beta tester I'd be more than willing to use it on my hotel :) Just let me know!

Those things will definitely be on there, the housekeeping panel is going to be very detailed. There has indeed been progress on this, but nothing that I can visually show you - I have changed the file structure to make things neater and removed the use of static classes. The code now uses a service container to handle all instance of classes and is much more heavily reliant on Dependency Injection (sticking to best practices) due to there going to be a lot of updates in the future.
 

Synt4x

Member
Jan 13, 2016
77
59
Alright thank you for the update. If you would like a beta tester I'd be more than willing to use it on my hotel :) Just let me know!
No problem at all. Thank you, do you have skype? If so, add me musecms
 
Status
Not open for further replies.

Users who are viewing this thread

Top