├── README.md ├── LICENSE ├── test.php └── XenForoSDK.php /README.md: -------------------------------------------------------------------------------- 1 | xenforo-sdk 2 | =========== 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vincent Gabriel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | isLoggedIn(); 7 | if($loggedIn) { 8 | echo 'Logged In'; 9 | } else { 10 | echo 'Guest'; 11 | } 12 | 13 | // Validate loing 14 | $valid = $sdk->validateLogin('test@test.com', 'password', $rememberMe, $loginUserIfSuccessful); 15 | 16 | if($valid !== true) { 17 | echo $valid; // will display the error 18 | } 19 | 20 | // Login user 21 | $user = $sdk->login($userId, $rememberMe); // no validation 22 | 23 | // Logout 24 | $sdk->logout(); 25 | 26 | // Hash password 27 | $passwrod = $sdk->setPassword('test123', 'passward_confirm'); // returns array scheme_class and data 28 | 29 | // Add new user 30 | $newUser = $sdk->addUser('test@test.com', 'myusername', 'mypassword', array('someotherdata' => 'someothervalue')); 31 | if(is_object($newUser)) { 32 | // user was not created show error 33 | echo $newUser; 34 | } else { 35 | // user created, $newUser holds id 36 | echo 'New User ID: ' . $newUser; 37 | } 38 | 39 | // Get all forums 40 | $forums = $sdk->getForums(); 41 | 42 | // Get one forum 43 | $forum = $sdk->getForumById(2); 44 | 45 | // Get all threads 46 | $threads = $sdk->getThreads(array()); // will show all so make sure to add conditions 47 | 48 | // Get one thread 49 | $thread = $sdk->getThreadById(2); 50 | 51 | // Get current user 52 | $user = $sdk->getUser(); 53 | 54 | // Get other user info 55 | $user = $sdk->getUser(2); 56 | 57 | // Get current visitor/session info 58 | $visitor = $sdk->getVisitor(); 59 | $session = $sdk->getSession(); 60 | 61 | // Get options/option 62 | $options = $sdk->getOptions(); 63 | $option = $sdk->getOption($key); 64 | 65 | // Render public/admin template 66 | $output = $sdk->renderPublicTemplate('template_name', array $params); 67 | $output = $sdk->renderAdminTemplate('template_name', array $params); 68 | 69 | 70 | -------------------------------------------------------------------------------- /XenForoSDK.php: -------------------------------------------------------------------------------- 1 | 9 | * @since 01/21/14 10 | * @version 0.0.1 11 | */ 12 | class XenForoSDK 13 | { 14 | public function __construct() { 15 | $startTime = microtime(true); 16 | $fileDir = XF_ROOT; 17 | 18 | require($fileDir . '/library/XenForo/Autoloader.php'); 19 | XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library'); 20 | 21 | XenForo_Application::initialize($fileDir . '/library', $fileDir); 22 | XenForo_Application::set('page_start_time', $startTime); 23 | XenForo_Session::startPublicSession(); 24 | } 25 | 26 | public function getVisitor() { 27 | return XenForo_Visitor::getInstance(); 28 | } 29 | 30 | public function getSession() { 31 | return XenForo_Application::get('session'); 32 | } 33 | 34 | public function getOptions() { 35 | return XenForo_Application::get('options'); 36 | } 37 | 38 | public function getOption($key, $val=null) { 39 | return $this->getOptions()->get($key, $val); 40 | } 41 | 42 | public function getUser($id=null) { 43 | // Make sure we are logged in 44 | if($id === null && !$this->getVisitor()->getUserId()) { 45 | return array(); 46 | } 47 | 48 | $userId = $id !== null ? $id : $this->getVisitor()->getUserId(); 49 | return XenForo_Model::create('XenForo_Model_User')->getFullUserById($userId); 50 | } 51 | 52 | public function isLoggedIn() { 53 | return $this->getVisitor()->getUserId(); 54 | } 55 | 56 | public function verifyUsername($username, $userId=null) { 57 | // standardize white space in names 58 | $username = preg_replace('/\s+/u', ' ', $username); 59 | try 60 | { 61 | $newName = preg_replace('/\v+/u', ' ', $username); 62 | if (is_string($newName)) 63 | { 64 | $username = $newName; 65 | } 66 | } 67 | catch (Exception $e) {} 68 | 69 | $username = trim($username); 70 | 71 | $usernameLength = utf8_strlen($username); 72 | $minLength = $this->getOption('usernameLength', 'min'); 73 | $maxLength = $this->getOption('usernameLength', 'max'); 74 | 75 | if ($minLength > 0 && $usernameLength < $minLength) 76 | { 77 | return new XenForo_Phrase('please_enter_name_that_is_at_least_x_characters_long', array('count' => $minLength)); 78 | } 79 | 80 | if ($maxLength > 0 && $usernameLength > $maxLength) 81 | { 82 | return new XenForo_Phrase('please_enter_name_that_is_at_most_x_characters_long', array('count' => $maxLength)); 83 | } 84 | 85 | $disallowedNames = preg_split('/\r?\n/', $this->getOption('usernameValidation', 'disallowedNames')); 86 | if ($disallowedNames) 87 | { 88 | foreach ($disallowedNames AS $name) 89 | { 90 | $name = trim($name); 91 | if ($name === '') 92 | { 93 | continue; 94 | } 95 | if (stripos($username, $name) !== false) 96 | { 97 | return new XenForo_Phrase('please_enter_another_name_disallowed_words'); 98 | } 99 | } 100 | } 101 | 102 | $matchRegex = $this->getOption('usernameValidation', 'matchRegex'); 103 | if ($matchRegex) 104 | { 105 | $matchRegex = str_replace('#', '\\#', $matchRegex); // escape delim only 106 | if (!preg_match('#' . $matchRegex . '#i', $username)) 107 | { 108 | return new XenForo_Phrase('please_enter_another_name_required_format'); 109 | } 110 | } 111 | 112 | $censoredUserName = XenForo_Helper_String::censorString($username); 113 | if ($censoredUserName !== $username) 114 | { 115 | return new XenForo_Phrase('please_enter_name_that_does_not_contain_any_censored_words'); 116 | } 117 | 118 | // ignore check if unicode properties aren't compiled 119 | try 120 | { 121 | if (@preg_match("/\p{C}/u", $username)) 122 | { 123 | return new XenForo_Phrase('please_enter_name_without_using_control_characters'); 124 | } 125 | } 126 | catch (Exception $e) {} 127 | 128 | if (strpos($username, ',') !== false) 129 | { 130 | return new XenForo_Phrase('please_enter_name_that_does_not_contain_comma'); 131 | } 132 | 133 | if (Zend_Validate::is($username, 'EmailAddress')) 134 | { 135 | return new XenForo_Phrase('please_enter_name_that_does_not_resemble_an_email_address'); 136 | } 137 | 138 | $existingUser = XenForo_Model::create('XenForo_Model_User')->getUserByName($username); 139 | if($existingUser && (!$userId || ($userId && $userId != $existingUser['user_id']))) { 140 | return new XenForo_Phrase('usernames_must_be_unique'); 141 | } 142 | 143 | // compare against romanized name to help reduce confusable issues 144 | $romanized = utf8_deaccent(utf8_romanize($username)); 145 | if ($romanized != $username) 146 | { 147 | $existingUser = XenForo_Model::create('XenForo_Model_User')->getUserByName($romanized); 148 | if($existingUser && (!$userId || ($userId && $userId != $existingUser['user_id']))) { 149 | return new XenForo_Phrase('usernames_must_be_unique'); 150 | } 151 | } 152 | 153 | return true; 154 | } 155 | 156 | public function verifyEmail($email, $userId=null) { 157 | if(!Zend_Validate::is($email, 'EmailAddress')) { 158 | return new XenForo_Phrase('please_enter_valid_email'); 159 | } 160 | 161 | $existingUser = XenForo_Model::create('XenForo_Model_User')->getUserByEmail($email); 162 | if($existingUser && (!$userId || ($userId && $userId != $existingUser['user_id']))) { 163 | return new XenForo_Phrase('email_addresses_must_be_unique'); 164 | } 165 | 166 | if(XenForo_Helper_Email::isEmailBanned($email)) { 167 | return new XenForo_Phrase('email_address_you_entered_has_been_banned_by_administrator'); 168 | } 169 | 170 | return true; 171 | } 172 | 173 | /** 174 | * Sets the user's password. 175 | * 176 | * @param string $password 177 | * @param string|false $passwordConfirm If a string, ensures that the password and the confirm are the same 178 | * @param XenForo_Authentication_Abstract|null $auth Auth object to generate the password (or null to use default) 179 | * @param boolean If true, do not accept an empty password 180 | * 181 | * @return boolean 182 | */ 183 | public function setPassword($password, $passwordConfirm = false, XenForo_Authentication_Abstract $auth = null, $requirePassword = false) 184 | { 185 | if ($requirePassword && $password === '') 186 | { 187 | return new XenForo_Phrase('please_enter_valid_password'); 188 | } 189 | 190 | if ($passwordConfirm !== false && $password !== $passwordConfirm) 191 | { 192 | return new XenForo_Phrase('passwords_did_not_match'); 193 | } 194 | 195 | if (!$auth) 196 | { 197 | $auth = XenForo_Authentication_Abstract::createDefault(); 198 | } 199 | 200 | $authData = $auth->generate($password); 201 | if (!$authData) 202 | { 203 | return new XenForo_Phrase('please_enter_valid_password'); 204 | } 205 | 206 | return array('scheme_class' => $auth->getClassName(), 'data' => $authData); 207 | } 208 | 209 | public function addUser($email, $username, $password, $additional=array()) { 210 | // Verify email 211 | $verifyEmail = $this->verifyEmail($email); 212 | if($verifyEmail !== true) { 213 | return $verifyEmail; 214 | } 215 | 216 | // Verify username 217 | $verifyUsername = $this->verifyUsername($username); 218 | if($verifyUsername !== true) { 219 | return $verifyUsername; 220 | } 221 | 222 | // Verify Password 223 | $userPassword = $this->setPassword($password); 224 | if(is_object($userPassword) && get_class($userPassword) == 'XenForo_Phrase') { 225 | return $userPassword; 226 | } 227 | 228 | // Replace spaces 229 | $username = str_replace(' ', '_', $username); 230 | 231 | // Create writer object 232 | $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); 233 | $info = array_merge($additional, array( 234 | 'username' => $username, 235 | 'email' => $email, 236 | 'user_group_id' => XenForo_Model_User::$defaultRegisteredGroupId, 237 | 'language_id' => $this->getVisitor()->get('language_id'), 238 | )); 239 | 240 | $writer->advanceRegistrationUserState(); 241 | 242 | $writer->bulkSet($info); 243 | 244 | // Set user password 245 | $writer->set('scheme_class', $userPassword['scheme_class']); 246 | $writer->set('data', $userPassword['data'], 'xf_user_authenticate'); 247 | 248 | // Save user 249 | $writer->save(); 250 | $user = $writer->getMergedData(); 251 | 252 | if(!$user['user_id']) { 253 | return new XenForo_Phrase('user_was_not_created'); 254 | } 255 | 256 | // log the ip of the user registering 257 | XenForo_Model_Ip::log($user['user_id'], 'user', $user['user_id'], 'register'); 258 | 259 | if ($user['user_state'] == 'email_confirm') { 260 | XenForo_Model::create('XenForo_Model_UserConfirmation')->sendEmailConfirmation($user); 261 | } 262 | 263 | return $user['user_id']; 264 | } 265 | 266 | public function validateLogin($email, $password, $remember=false, $doLogin=false) { 267 | // Init 268 | $loginModel = XenForo_Model::create('XenForo_Model_Login'); 269 | $userModel = XenForo_Model::create('XenForo_Model_User'); 270 | $hasError = null; 271 | 272 | // Validate user info 273 | $user = $userModel->validateAuthentication($email, $password, $hasError); 274 | if(!$user) { 275 | $loginModel->logLoginAttempt($email); 276 | return new XenForo_Phrase($hasError); 277 | } 278 | 279 | // Clear login attempts 280 | $loginModel->clearLoginAttempts($email); 281 | 282 | // Login 283 | if($doLogin) { 284 | return $this->login($user, $remember); 285 | } 286 | 287 | // This just validates the login info 288 | // so a bool is a good idea to return here 289 | return true; 290 | } 291 | 292 | public function login($user, $remember=false) { 293 | $userModel = XenForo_Model::create('XenForo_Model_User'); 294 | 295 | // Set cookie if needed 296 | if($remember) { 297 | $userModel->setUserRememberCookie($user); 298 | } 299 | 300 | // Log IP 301 | XenForo_Model_Ip::log($user, 'user', $user, 'login'); 302 | 303 | // delete current session 304 | $userModel->deleteSessionActivity(0, $_SERVER['REMOTE_ADDR']); 305 | 306 | $this->getSession()->changeUserId($user); 307 | $this->getVisitor()->setup($user); 308 | 309 | return $user; 310 | } 311 | 312 | public function adminLogout() { 313 | $session = new XenForo_Session(array('admin' => true)); 314 | $session->start(); 315 | if ($session->get('user_id') == $this->getVisitor()->getUserId()) { 316 | return $session->delete(); 317 | } 318 | 319 | return true; 320 | } 321 | 322 | public function logout() { 323 | // Check if we are an admin 324 | if($this->getVisitor()->get('is_admin')) { 325 | // Logout admin 326 | $this->adminLogout(); 327 | } 328 | 329 | // Logout user 330 | XenForo_Model::create('XenForo_Model_Session')->processLastActivityUpdateForLogOut($this->getVisitor()->getUserId()); 331 | $this->getSession()->delete(); 332 | 333 | XenForo_Helper_Cookie::deleteAllCookies(array('session'), array('user' => array('httpOnly' => false))); 334 | $this->getVisitor()->setup(0); 335 | 336 | return true; 337 | } 338 | 339 | public function getForumById($id, $fetchOptions=array()) { 340 | return XenForo_Model::create('XenForo_Model_Forum')->getForumById($id, $fetchOptions); 341 | } 342 | 343 | public function getForumsByIds($ids, $fetchOptions=array()) { 344 | return XenForo_Model::create('XenForo_Model_Forum')->getForumsByIds($ids, $fetchOptions); 345 | } 346 | 347 | public function getForums(array $conditions = array(), array $fetchOptions = array()) { 348 | return XenForo_Model::create('XenForo_Model_Forum')->getForums($conditions, $fetchOptions); 349 | } 350 | 351 | public function getThreadsByIds($ids, $fetchOptions=array()) { 352 | return XenForo_Model::create('XenForo_Model_Thread')->getThreadsByIds($ids, $fetchOptions); 353 | } 354 | 355 | public function getThreadById($id, $fetchOptions=array()) { 356 | return XenForo_Model::create('XenForo_Model_Thread')->getThreadById($id, $fetchOptions); 357 | } 358 | 359 | public function getThreads(array $conditions, array $fetchOptions = array()) { 360 | return XenForo_Model::create('XenForo_Model_Thread')->getThreads($conditions, $fetchOptions); 361 | } 362 | 363 | public function renderTemplate($name, $params=array(), $styleId=null, $languageId=null) { 364 | // user 365 | $user = $this->getUser(); 366 | 367 | // Template 368 | $template = new XenForo_Template_Public($name, $params); 369 | $template->setStyleId(($styleId!==null ? $styleId : $user['style_id'])); 370 | $template->setLanguageId(($languageId!==null ? $languageId : $user['language_id'])); 371 | 372 | return $template->render(); 373 | } 374 | 375 | public function renderAdminTemplate($name, $params=array(), $styleId=null, $languageId=null) { 376 | // user 377 | $user = $this->getUser(); 378 | 379 | // Template 380 | $template = new XenForo_Template_Admin($name, $params); 381 | $template->setStyleId(($styleId!==null ? $styleId : $user['style_id'])); 382 | $template->setLanguageId(($languageId!==null ? $languageId : $user['language_id'])); 383 | 384 | return $template->render(); 385 | } 386 | } --------------------------------------------------------------------------------