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?
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)
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:
Login Controller
Avatar Controller
Example of a routing file:
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.
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' ) );
}
}
}
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.
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:
You must be registered for see links
Credits:
Xenon (Avatar)
Myself (Design and coding)
Last edited: