diff --git a/README.md b/README.md index e8ed055..902fc68 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,42 @@ XenforoBridge ============= -Simple to use XenForo bridge libary. The goal of this package is to allow developer to easily integrate their existing/new application with XenForo Forum Platfrom. This package is still heavily underdevelopment so use with caution. I have also included a ServiceProvider to use within a Laravel application. +Simple to use XenForo bridge library. The goal of this package is to allow developer to easily integrate their existing/new application with XenForo Forum Platfrom. This package is still heavily underdevelopment so use with caution. I have also included a ServiceProvider to use within a Laravel application. Installation ------------ -Install the XenforoBridge package with Composer. +Install the XenforoBridge package with Composer by adding the folowing to your composer.json file. ```json { "require": { - "urb/xenforobridge": "dev-master" + "urb/xenforobridge": "dev-development" } } ``` +Or by using the composer require command -To install XenforoBridge into Laravel 4 simple add the following service provider to your 'app/config/app.php' in the 'providers' array: +``` +composer require urb/xenforobridge:dev-development +``` + +To install XenforoBridge into Laravel 5 simple add the following service provider to your 'config/app.php' in the 'providers' array: ```php 'providers' => array( - 'XenforoBridge\XenforoBridgeServiceProvider', + 'XenforoBridge\XenforoBridgeServiceProvider::class', ) ``` -Then publish the config file with 'php artisan config:publish urb/xenforobridge'. This will add the file 'app/config/packages/urb/xenforobridge/config.php'. This is where you will place the needed configurations to use the Xenforo Bridge. + +Then publish the config file with + +``` +php artisan vendor:publish +``` + +This will add the file 'config/xenforobridge.php'. This is where you will place the needed configurations to use the Xenforo Bridge. Within this config file you will need to supply the full directory path to your XenForo installation and the base url path like the example below @@ -35,6 +47,47 @@ return array( ); ``` +Installing Middleware +--------------------- +To install Middleware you wil need to open up the app\Http\Kernel.php and the following middleware to either global middleware array +or the routeMiddleware array. + +Here is an example adding to the routeMiddleware array + +```php +protected $routeMiddleware = [ + 'xen.auth' => 'XenforoBridge\Middleware\XenAuthMiddleware', + 'xen.auth.admin' => 'XenforoBridge\Middleware\XenAuthAdminMiddleware', + ]; + +``` + +You can then use them in your routes like so + +```php +Route::get('/example', ['middleware' => 'xen.auth',function(){ + //Do stuff +}]); +``` + +or you can use them in your controllers themselves + +```php +class SampleController extends Controller { + + + function __construct() + { + + $this->middleware('xen.auth'); + } + +} + +``` + +For more information on Middleware development an installation check out [Laravel Docs - Middleware](http://laravel.com/docs/5.1/middleware) + Credits ------- diff --git a/composer.json b/composer.json index 48006c9..931702c 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "urb/xenforobridge", - "description": "Xenforo Bridge - Easy to use extendable bridge to use outside of your XenForo application all containted within a simple to use composer package", - "keywords": ["laravel", "laravel4", "xenforo", "xenforo forum", "forum"], + "description": "Xenforo Bridge - Easy to use extendable bridge to use outside of your XenForo application all contained within a simple to use composer package", + "keywords": ["laravel", "laravel5", "xenforo", "xenforo forum", "forum"], "type": "library", "authors": [ { @@ -10,7 +10,7 @@ } ], "require": { - "php": ">=5.3.0" + "php": ">=5.5.0" }, "autoload": { "psr-0": { diff --git a/src/XenforoBridge/Contracts/TemplateInterface.php b/src/XenforoBridge/Contracts/TemplateInterface.php index 1aea451..56ad5cf 100644 --- a/src/XenforoBridge/Contracts/TemplateInterface.php +++ b/src/XenforoBridge/Contracts/TemplateInterface.php @@ -2,5 +2,6 @@ interface TemplateInterface { - + + public function renderTemplate($name, $content, $params); } \ No newline at end of file diff --git a/src/XenforoBridge/Contracts/UserInterface.php b/src/XenforoBridge/Contracts/UserInterface.php new file mode 100644 index 0000000..52ac88a --- /dev/null +++ b/src/XenforoBridge/Contracts/UserInterface.php @@ -0,0 +1,11 @@ +xenforo->isSuperAdmin() AND ! $this->xenforo->isBanned()) + if(!$this->xenforo->isAdmin() AND ! $this->xenforo->isBanned()) { Session::put('loginRedirect', $request->url()); return Redirect::to($xenBaseUrl.'login'); diff --git a/src/XenforoBridge/User/User.php b/src/XenforoBridge/User/User.php index 6e8fc8f..b0810b5 100644 --- a/src/XenforoBridge/User/User.php +++ b/src/XenforoBridge/User/User.php @@ -1,29 +1,170 @@ setUser(new XenforoUser); } - public function isBanned() + /** + * Set User Model + * + * @param XenforoUser $user + */ + public function setUser(XenforoUser $user) { - return $this->getCurrentVisitor()->toArray()['is_banned']; + $this->user = $user; } - public function isSuperAdmin() + /** + * Get User Model + * + * @return void|XenforoUser + */ + public function getUser() { - return $this->getCurrentVisitor()->isSuperAdmin(); + return $this->user; } - public function isLoggedIn() + /** + * Get User by Id - returns empty array if user does not exist + * + * @param $id + * @return array + */ + public function getUserById($id) { - return $this->getCurrentVisitor()->getUserId(); + return $this->user->getUserById($id)?:[]; + } + + /** + * Get User by Email - returns empty array if user does not exist + * + * @param $email + * @return array + */ + public function getUserByEmail($email) + { + return $this->user->getUserByEmail($email)?: []; + } + + /** + * Get User by Username - returns empty array if user does not exist + * + * @param $name + * @return array + */ + public function getUserByUsername($name) + { + return $this->user->getUserByName($name)?:[]; + } + + /** + * Validates Passwords and Returns Hashed value + * + * @todo refactor this method clean up and break down into smaller methods also rename to better illustrate it's purpose + * @param $password + * @param bool|false $passwordConfirm + * @param XenForo_Authentication_Abstract|null $auth + * @param bool|false $requirePassword + * @return array|XenForo_Phrase + */ + public function setPassword($password, $passwordConfirm = false, XenForo_Authentication_Abstract $auth = null, $requirePassword = false) + { + if ($requirePassword && $password === '') + { + return new XenForo_Phrase('please_enter_valid_password'); + } + if ($passwordConfirm !== false && $password !== $passwordConfirm) + { + return new XenForo_Phrase('passwords_did_not_match'); + } + if (!$auth) + { + $auth = XenForo_Authentication_Abstract::createDefault(); + } + $authData = $auth->generate($password); + if (!$authData) + { + return new XenForo_Phrase('please_enter_valid_password'); + } + return array('scheme_class' => $auth->getClassName(), 'data' => $authData); + } + + /** + * Add User to Xenforo + * + * @todo refactor this method clean up and break down into smaller methods + * @param $email + * @param $username + * @param $password + * @param array $additional + * @param int $languageId + * @return array|XenForo_Phrase + * @throws \Exception + * @throws \XenForo_Exception + */ + public function addUser($email,$username,$password,array $additional = [], $languageId = XenforoBridge::XENFOROBRIDGE_DEFAULT_LANGUAGE_ID) + { + // Verify Password + $userPassword = $this->setPassword($password); + if(is_object($userPassword) && get_class($userPassword) == 'XenForo_Phrase') { + return $userPassword; + } + + /** + * @var $writer \XenForo_DataWriter_User + */ + $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); + + $info = array_merge($additional, array( + 'username' => $username, + 'email' => $email, + 'user_group_id' => XenforoUser::$defaultRegisteredGroupId, + 'language_id' => $languageId, + )); + + $writer->advanceRegistrationUserState(); + + $writer->bulkSet($info); + + // Set user password + $writer->set('scheme_class', $userPassword['scheme_class']); + $writer->set('data', $userPassword['data'], 'xf_user_authenticate'); + + // Save user + $writer->save(); + $user = $writer->getMergedData(); + + if(!$user['user_id']) { + return new XenForo_Phrase('user_was_not_created'); + } + // log the ip of the user registering + XenForo_Model_Ip::log($user['user_id'], 'user', $user['user_id'], 'register'); + + /*if ($user['user_state'] == 'email_confirm') { + XenForo_Model::create('XenForo_Model_UserConfirmation')->sendEmailConfirmation($user); + }*/ + return $user['user_id']; } } diff --git a/src/XenforoBridge/Visitor/Visitor.php b/src/XenforoBridge/Visitor/Visitor.php index 305be6e..8d38565 100644 --- a/src/XenforoBridge/Visitor/Visitor.php +++ b/src/XenforoBridge/Visitor/Visitor.php @@ -14,16 +14,26 @@ public function getCurrentVisitor() public function isBanned() { - return $this->getCurrentVisitor()->toArray()['is_banned']; + return (bool)$this->getCurrentVisitor()->toArray()['is_banned']; } + public function isAdmin() + { + return (bool)$this->getCurrentVisitor()->toArray()['is_admin']; + } + public function isSuperAdmin() { - return $this->getCurrentVisitor()->isSuperAdmin(); + return (bool)$this->getCurrentVisitor()->isSuperAdmin(); } public function isLoggedIn() { - return $this->getCurrentVisitor()->getUserId(); + return (bool)$this->getCurrentVisitor()->getUserId(); + } + + public function hasPermission($group,$permission) + { + return $this->getCurrentVisitor()->hasPermission($group,$permission); } } diff --git a/src/XenforoBridge/XenforoBridge.php b/src/XenforoBridge/XenforoBridge.php index 897e183..e68fd05 100644 --- a/src/XenforoBridge/XenforoBridge.php +++ b/src/XenforoBridge/XenforoBridge.php @@ -1,106 +1,401 @@ xenforoDir = $xenforoDir; + /** + * Default language id for Xenforo + */ + const XENFOROBRIDGE_DEFAULT_LANGUAGE_ID = 1; - //Load Xenforo Autoloader - $this->loadXenAutoloader($xenforoDir); + /** + * Absolute Path to Xenforo Directory + * (ex. /home/username/www/forums/ ) + * + * @var string + */ + protected $xenforoDirectoryPath; - //Intialize Xenforo Application - XenForo_Autoloader::getInstance()->setupAutoloader($xenforoDir .'/library'); - XenForo_Application::initialize($xenforoDir . '/library', $xenforoDir); - //XenForo_Application::set('page_start_time', $startTime); - XenForo_Session::startPublicSession(); + /** + * Base Url to Xenforo Application + * (ex. http://example.com/forums | http://example.com) + * + * @var string + */ + protected $xenforoBaseUrl; - //Load XenforoBridge Modules - $this->setVisitor(new Visitor); - $this->setTemplate(new Template($xenforoBaseUrl)); - } + /** + * @var \XenForo_Options + */ + protected $xenforoOptions; - public function setVisitor(VisitorInterface $visitor) - { - $this->visitor = $visitor; - } + /** + * @var VisitorInterface + */ + protected $visitor; - public function setTemplate(TemplateInterface $template) - { - $this->template = $template; - } + /** + * @var TemplateInterface + */ + protected $template; - /** - * Attempts to load Xenforo_Autloader.php throws exception if - * unable to find or load. - * - * @param string $xenforoDir - Full path to Xenforo Directory - * @return boolean - */ - protected function loadXenAutoloader($xenforoDir) + /** + * @var UserInterface + */ + protected $user; + + /** + * Bootstrap XenforoBridge + * + * @param $xenforoDirectoryPath + * @param null|string $xenforoBaseUrl + * @throws XenforoAutoloaderException + */ + public function __construct($xenforoDirectoryPath, $xenforoBaseUrl = null) + { + $this->xenforoDirectoryPath = $xenforoDirectoryPath; + + //Load Xenforo Autoloader + $this->loadXenAutoloader($this->xenforoDirectoryPath); + + //Bootstrap Xenforo App + $this->bootstrapXenforo($this->xenforoDirectoryPath); + + //Set Xenforo Base Url + $this->setXenforoBaseUrl($xenforoBaseUrl); + } + + /** + * Set Xenforo Base Url + * + * @param null|string $url + */ + public function setXenforoBaseUrl($url = null) + { + $this->xenforoBaseUrl = $this->retrieveXenforoBaseUrl($url); + } + + /** + * Retrieve Xenforo Application base url from Xenforo itself if none is supplied + * + * @param null|string $url + * @return mixed|null|string + */ + public function retrieveXenforoBaseUrl($url = null) + { + if(!is_null($url)) + { + return $url; + } + + return $this->getXenforoOptionById(self::XENFORO_OPTION_BASE_URL); + } + + /** + * @return mixed|null|string + */ + public function getXenforoBaseUrl() + { + if(!$this->xenforoBaseUrl) + { + $this->xenforoBaseUrl = $this->retrieveXenforoBaseUrl(); + } + + return $this->xenforoBaseUrl; + } + /** + * Bootstrap Xenforo Application and Start a Public Session + * + * @param string $directoryPath + */ + protected function bootstrapXenforo($directoryPath) + { + XenForo_Autoloader::getInstance()->setupAutoloader($directoryPath .'/library'); + XenForo_Application::initialize($directoryPath . '/library', $directoryPath); + XenForo_Session::startPublicSession(); + } + + /** + * Get all Xenforo Options + * + * @return mixed|XenForo_Options + * @throws \Zend_Exception + */ + public function getXenforoOptions() + { + if(!$this->xenforoOptions instanceof XenForo_Options) + { + $this->xenforoOptions = XenForo_Application::get('options'); + } + return $this->xenforoOptions; + } + + /** + * Get Xenforo Option by id + * + * @param string $id + * @return mixed|null + */ + public function getXenforoOptionById($id) + { + return $this->getXenforoOptions()->get($id); + } + + /** + * Attempts to load Xenforo_Autoloader.php throws exception if + * unable to find or load. + * + * @param string $xenforoDirectory - Full path to Xenforo Directory + * @return bool + * @throws XenforoAutoloaderException + */ + protected function loadXenAutoloader($xenforoDirectory) { - $path = $xenforoDir. '/library/XenForo/Autoloader.php'; + $path = $xenforoDirectory. '/library/XenForo/Autoloader.php'; $autoloader = include($path); if(!$autoloader) { - throw new XenforoAutloaderException('Could not load XenForo_Autoloader.php check path'); + throw new XenforoAutoloaderException('Could not load XenForo_Autoloader.php check path'); } } - public function getVisitor() - { - return $this->visitor->getCurrentVisitor(); - } + /** + * Retrieve Visitor Class + * + * @return VisitorInterface + */ + public function retrieveVisitor() + { + if(!$this->visitor instanceof VisitorInterface) + { + $this->setVisitor(new Visitor); + } + + return $this->visitor; + } + + /** + * Set a new Visitor implementation + * + * @param VisitorInterface $visitor + */ + public function setVisitor(VisitorInterface $visitor) + { + $this->visitor = $visitor; + } + + /** + * Gets singleton instance of Xenforo_Visitor + * + * @return \XenForo_Visitor + */ + public function getVisitor() + { + return $this->retrieveVisitor()->getCurrentVisitor(); + } + + /** + * Checks if current visitor is banned + * + * @return boolean + */ + public function isBanned() + { + return (bool)$this->retrieveVisitor()->isBanned(); + } - public function isBanned() + /** + * Checks if current visitor is an Admin + * + * @return boolean + */ + public function isAdmin() { - return $this->visitor->isBanned(); + return $this->retrieveVisitor()->isAdmin(); } + /** + * Checks if visitor is a Super Admin + * + * @return boolean + */ public function isSuperAdmin() { - return $this->visitor->isSuperAdmin(); + return $this->retrieveVisitor()->isSuperAdmin(); } + /** + * Checks if visitor is currently logged in + * + * @return boolean + */ public function isLoggedIn() { - return $this->visitor->isLoggedIn(); + return $this->retrieveVisitor()->isLoggedIn(); } + /** + * Checks if visitor has a particular permission + * + * @param $group - permission group + * @param $permission - permission + * @return mixed + */ + public function hasPermission($group,$permission) + { + return $this->retrieveVisitor()->hasPermission($group,$permission); + } + + /** + * Retrieve Template set default implementation if one is not set already + * + * @return TemplateInterface + */ + public function retrieveTemplate() + { + if(!$this->template instanceof TemplateInterface) + { + $this->setTemplate(new Template($this->getXenforoBaseUrl())); + } + + return $this->template; + } + + /** + * Set Template + * + * @param TemplateInterface $template + */ + public function setTemplate(TemplateInterface $template) + { + $this->template = $template; + } + + /** + * Get current implementation of Template + * + * @return TemplateInterface + */ + public function getTemplate() + { + return $this->retrieveTemplate(); + } + + /** + * Render a Xenforo Template + * + * @todo simplify method signature reverse the order of content parameter + * + * @param string $name - template_id + * @param string $content - this will override the entire content area of the template + * @param array $params - parameters pasted to the template renderer + * @return mixed + */ public function renderTemplate( $name = 'PAGE_CONTAINER', $content = '', $params = array()) { - return $this->template->renderTemplate($name,$content,$params); + return $this->getTemplate()->renderTemplate($name,$content,$params); + } + + /** + * Return current implementation or set Default User + * + * @return UserInterface + */ + public function retrieveUser() + { + if(!$this->user instanceof UserInterface) + { + $this->setUser(new User); + } + + return $this->user; + } + + /** + * Set current implementation of User + * + * @param UserInterface $user + */ + public function setUser(UserInterface $user) + { + $this->user = $user; + } + + /** + * Return current User implementation + * + * @return UserInterface + */ + public function getUser() + { + return $this->retrieveUser(); + } + + /** + * Find User by Id + * + * @param $id + * @return array + */ + public function getUserById($id) + { + return $this->getUser()->getUserById($id); } /** - * Retrieve Xenforo User by Id + * Retrieve Xenforo User by Email * * If no user is found returns empty array * - * @param $id + * @param $email * @return array */ - public function getUserById($id) + public function getUserByEmail($email) + { + return $this->getUser()->getUserByEmail($email); + } + + /** + * Get Xenforo User by Username - if no user is found returns empty array + * + * @param $name + * @return array + */ + public function getUserByName($name) { - return (new Xenforo_Model_User)->getUserById($id)?:[]; + return $this->getUser()->getUserByUsername($name); } + }