Merged in settings-options-backend (pull request #29)

Settings options backend
This commit is contained in:
Ivan Diaz 2016-08-02 15:09:16 -03:00
commit 4d5ce7022e
19 changed files with 251 additions and 52 deletions

View File

@ -0,0 +1,30 @@
<?php
use Respect\Validation\Validator as DataValidator;
class GetSettingController extends Controller {
const PATH = '/get-setting';
public function validations() {
return [
'permission' => 'any',
'requestData' => [
'name' => [
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_SETTING
]
]
];
}
public function handler() {
$setting = Setting::getSetting(Controller::request('name'));
if (!$setting->isNull()) {
Response::respondSuccess([
'setting' => $setting->value
]);
} else {
Response::respondError(ERRORS::INVALID_SETTING);
}
}
}

View File

@ -0,0 +1,35 @@
<?php
use Respect\Validation\Validator as DataValidator;
class GetSettingController extends Controller {
const PATH = '/get-setting';
public function validations() {
return [
'permission' => 'any',
'requestData' => [
'name' => [
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_SETTING
],
'value' => [
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_SETTING
]
]
];
}
public function handler() {
$setting = Setting::getSetting(Controller::request('name'));
if (!$setting->isNull()) {
$setting->value = Controller::request('value');
$setting->store();
Response::respondSuccess();
} else {
Response::respondError(ERRORS::INVALID_SETTING);
}
}
}

View File

@ -1,5 +1,4 @@
<?php <?php
use RedBeanPHP\Facade as RedBean;
use Respect\Validation\Validator as DataValidator; use Respect\Validation\Validator as DataValidator;
class CreateController extends Controller { class CreateController extends Controller {

View File

@ -4,7 +4,6 @@ class LoginController extends Controller {
const PATH = '/login'; const PATH = '/login';
private $userInstance; private $userInstance;
private $session;
private $rememberToken; private $rememberToken;
public function validations() { public function validations() {
@ -20,7 +19,7 @@ class LoginController extends Controller {
return; return;
} }
if ($this->areCredentialsValid() || $this->isRememberTokenValid()) { if ($this->checkInputCredentials() || $this->checkRememberToken()) {
$this->createUserSession(); $this->createUserSession();
$this->createSessionCookie(); $this->createSessionCookie();
@ -31,61 +30,61 @@ class LoginController extends Controller {
} }
private function isAlreadyLoggedIn() { private function isAlreadyLoggedIn() {
return $this->getSession()->sessionExists(); return Session::getInstance()->sessionExists();
} }
private function areCredentialsValid() { private function checkInputCredentials() {
return ($this->getUserByInputCredentials() !== null); $this->userInstance = $this->getUserByInputCredentials();
return !$this->userInstance->isNull();
} }
private function isRememberTokenValid() { private function checkRememberToken() {
$rememberToken = Controller::request('rememberToken'); $this->userInstance = $this->getUserByRememberToken();
if ($rememberToken) { return !$this->userInstance->isNull();
$sessionCookie = SessionCookie::getDataStore($rememberToken, 'token');
$userid = Controller::request('userId');
if ($sessionCookie !== null && $userid === $sessionCookie->user->id) {
$this->userInstance = $sessionCookie->user;
return true;
}
}
} }
private function createUserSession() { private function createUserSession() {
$this->getSession()->createSession($this->userInstance->id); Session::getInstance()->createSession($this->userInstance->id);
} }
private function getUserData() { private function getUserData() {
$userInstance = $this->getUserByInputCredentials(); $userInstance = $this->userInstance;
return array( return array(
'userId' => $userInstance->id, 'userId' => $userInstance->id,
'userEmail' => $userInstance->email, 'userEmail' => $userInstance->email,
'token' => $this->getSession()->getToken(), 'token' => Session::getInstance()->getToken(),
'rememberToken' => $this->rememberToken 'rememberToken' => $this->rememberToken
); );
} }
private function getUserByInputCredentials() { private function getUserByInputCredentials() {
if ($this->userInstance === null) { $email = Controller::request('email');
$email = Controller::request('email'); $password = Controller::request('password');
$password = Controller::request('password');
$this->userInstance = User::authenticate($email, $password); return User::authenticate($email, $password);
}
private function getUserByRememberToken() {
$rememberToken = Controller::request('rememberToken');
$userInstance = new NullDataStore();
if ($rememberToken) {
$sessionCookie = SessionCookie::getDataStore($rememberToken, 'token');
$userId = Controller::request('userId');
if (!$sessionCookie->isNull() && $userId === $sessionCookie->user->id) {
$userInstance = new User($sessionCookie->user);
$sessionCookie->trash();
}
} }
return $this->userInstance; return $userInstance;
} }
private function getSession() { private function createSessionCookie() {
if ($this->session === null) {
$this->session = Session::getInstance();
}
return $this->session;
}
private function createSessionCookie(){
$remember = Controller::request('remember'); $remember = Controller::request('remember');
if ($remember) { if ($remember) {
$this->rememberToken = Hashing::generateRandomToken(); $this->rememberToken = Hashing::generateRandomToken();

View File

@ -8,5 +8,6 @@ class ERRORS {
const INVALID_EMAIL = 'Invalid email'; const INVALID_EMAIL = 'Invalid email';
const INVALID_PASSWORD = 'Invalid password'; const INVALID_PASSWORD = 'Invalid password';
const INVALID_NAME = 'Invalid name'; const INVALID_NAME = 'Invalid name';
const INVALID_SETTING = 'Invalid setting';
const INIT_SETTINGS_DONE = 'Settings already initialized'; const INIT_SETTINGS_DONE = 'Settings already initialized';
} }

View File

@ -4,12 +4,12 @@ class MailSender {
private $mailOptions = []; private $mailOptions = [];
public function __construct() { public function __construct() {
$this->mailOptions['from'] = Setting::getSetting('no-reply-email'); $this->mailOptions['from'] = Setting::getSetting('no-reply-email')->value;
$this->mailOptions['smtp-host'] = Setting::getSetting('smtp-host'); $this->mailOptions['smtp-host'] = Setting::getSetting('smtp-host')->value;
$this->mailOptions['smtp-port'] = Setting::getSetting('smtp-host'); $this->mailOptions['smtp-port'] = Setting::getSetting('smtp-host')->value;
$this->mailOptions['smtp-user'] = Setting::getSetting('smtp-host'); $this->mailOptions['smtp-user'] = Setting::getSetting('smtp-host')->value;
$this->mailOptions['smtp-pass'] = Setting::getSetting('smtp-host'); $this->mailOptions['smtp-pass'] = Setting::getSetting('smtp-host')->value;
} }
public function setTemplate($type, $config) { public function setTemplate($type, $config) {

View File

@ -13,7 +13,7 @@ abstract class DataStore {
':value' => $value ':value' => $value
)); ));
return ($bean) ? new static($bean) : null; return ($bean) ? new static($bean) : new NullDataStore();
} }
public function __construct($beanInstance = null) { public function __construct($beanInstance = null) {
@ -80,4 +80,8 @@ abstract class DataStore {
public function trash() { public function trash() {
RedBean::trash($this->_bean); RedBean::trash($this->_bean);
} }
public function isNull() {
return false;
}
} }

View File

@ -8,14 +8,14 @@ class MailTemplate extends DataStore {
const USER_PASSWORD = 'USER_PASSWORD'; const USER_PASSWORD = 'USER_PASSWORD';
public static function getTemplate($type) { public static function getTemplate($type) {
$globalLanguage = Setting::getSetting('language'); $globalLanguage = Setting::getSetting('language')->value;
$bean = RedBean::findOne(MailTemplate::TABLE, 'type = :type AND language = :language', array( $bean = RedBean::findOne(MailTemplate::TABLE, 'type = :type AND language = :language', array(
':type' => $type, ':type' => $type,
':language' => $globalLanguage ':language' => $globalLanguage
)); ));
return ($bean) ? new MailTemplate($bean) : null; return ($bean) ? new MailTemplate($bean) : new NullDataStore();
} }
public static function getProps() { public static function getProps() {

View File

@ -0,0 +1,21 @@
<?php
class NullDataStore extends DataStore {
const TABLE = null;
public function __construct() {
$this->_bean = null;
}
public function isNull() {
return true;
}
public function getProps() {
return [];
}
public function store() {
return null;
}
}

View File

@ -4,9 +4,7 @@ class Setting extends DataStore {
const TABLE = 'setting'; const TABLE = 'setting';
public static function getSetting($name) { public static function getSetting($name) {
$dataStore = parent::getDataStore($name, 'name'); return parent::getDataStore($name, 'name');
return ($dataStore !== null) ? $dataStore->value : null;
} }
public static function getProps() { public static function getProps() {

View File

@ -7,7 +7,7 @@ class User extends DataStore {
public static function authenticate($userEmail, $userPassword) { public static function authenticate($userEmail, $userPassword) {
$user = User::getUser($userEmail, 'email'); $user = User::getUser($userEmail, 'email');
return ($user && Hashing::verifyPassword($userPassword, $user->password)) ? $user : null; return ($user && Hashing::verifyPassword($userPassword, $user->password)) ? $user : new NullDataStore();
} }
public static function getProps() { public static function getProps() {

View File

@ -0,0 +1,41 @@
<?php
class BeanMock implements ArrayAccess {
private $properties;
public function __construct($array = []) {
$this->properties = $array;
}
public function offsetSet($offset, $value) {
$this->__set($offset, $value);
}
public function offsetExists($offset) {
return $this->__isset($offset);
}
public function offsetUnset($offset) {
$this->__unset($offset);
}
public function &offsetGet($offset) {
return $this->__get($offset);
}
public function &__get($property) {
return $this->properties[$property];
}
public function __set($property, $value) {
$this->properties[$property] = $value;
}
public function __isset($property) {
return isset($this->properties[$property]);
}
public function __unset($property) {
unset($this->properties[$property]);
}
}

View File

@ -0,0 +1,7 @@
<?php
class NullDataStore extends \Mock {
public function isNull() {
return true;
}
}

View File

@ -1,5 +1,8 @@
<?php <?php
namespace RedBeanPHP { namespace RedBeanPHP {
include_once 'tests/__mocks__/BeanMock.php';
class Facade extends \Mock { class Facade extends \Mock {
public static $functionList = array(); public static $functionList = array();
@ -7,7 +10,7 @@ namespace RedBeanPHP {
self::setStatics(array( self::setStatics(array(
'trash' => parent::stub(), 'trash' => parent::stub(),
'store' => parent::stub(), 'store' => parent::stub(),
'dispense' => parent::stub()->returns(array()) 'dispense' => parent::stub()->returns(new \BeanMock())
)); ));
} }
} }

View File

@ -0,0 +1,26 @@
<?php
include_once 'tests/__mocks__/BeanMock.php';
class Setting extends \Mock {
public static $functionList = array();
public static function initStubs() {
parent::setStatics(array(
'getSetting' => parent::stub()->returns(self::getSettingInstanceMock()),
'setSetting' => parent::stub()
));
}
public function isNull() {
return false;
}
private static function getSettingInstanceMock() {
$mockUserInstance = new BeanMock();
$mockUserInstance->name = 'MOCK_SETTING_NAME';
$mockUserInstance->value = 'MOCK_SETTING_VALUE';
return $mockUserInstance;
}
}

View File

@ -7,9 +7,13 @@ class User extends \Mock {
'authenticate' => parent::stub()->returns(self::getUserInstanceMock()), 'authenticate' => parent::stub()->returns(self::getUserInstanceMock()),
)); ));
} }
public function isNull() {
return false;
}
private static function getUserInstanceMock() { private static function getUserInstanceMock() {
$mockUserInstance = new \stdClass(); $mockUserInstance = new User();
$mockUserInstance->id = 'MOCK_ID'; $mockUserInstance->id = 'MOCK_ID';
$mockUserInstance->email = 'MOCK_EMAIL'; $mockUserInstance->email = 'MOCK_EMAIL';

View File

@ -1,6 +1,7 @@
<?php <?php
// MOCKS // MOCKS
include_once 'tests/__lib__/Mock.php'; include_once 'tests/__lib__/Mock.php';
include_once 'tests/__mocks__/NullDataStoreMock.php';
include_once 'tests/__mocks__/ResponseMock.php'; include_once 'tests/__mocks__/ResponseMock.php';
include_once 'tests/__mocks__/ControllerMock.php'; include_once 'tests/__mocks__/ControllerMock.php';
include_once 'tests/__mocks__/SessionMock.php'; include_once 'tests/__mocks__/SessionMock.php';
@ -45,7 +46,7 @@ class LoginControllerTest extends PHPUnit_Framework_TestCase {
public function testShouldRespondErrorIfCredentialsAreInvalid() { public function testShouldRespondErrorIfCredentialsAreInvalid() {
User::setStatics(array( User::setStatics(array(
'authenticate' => \Mock::stub()->returns(null) 'authenticate' => \Mock::stub()->returns(new NullDataStore())
)); ));
$this->loginController->handler(); $this->loginController->handler();

View File

@ -1,5 +1,6 @@
<?php <?php
include_once 'tests/__lib__/Mock.php'; include_once 'tests/__lib__/Mock.php';
include_once 'tests/__mocks__/BeanMock.php';
include_once 'tests/__mocks__/SlimMock.php'; include_once 'tests/__mocks__/SlimMock.php';
include_once 'tests/__mocks__/RedBeanMock.php'; include_once 'tests/__mocks__/RedBeanMock.php';
include_once 'models/DataStore.php'; include_once 'models/DataStore.php';
@ -57,7 +58,7 @@ class DataStoreTest extends PHPUnit_Framework_TestCase {
public function testGetDataStore() { public function testGetDataStore() {
RedBean::setStatics(array( RedBean::setStatics(array(
'findOne' => \Mock::stub()->returns(array('TEST_PROP' => 'TEST_VALUE')) 'findOne' => \Mock::stub()->returns(new BeanMock(['TEST_PROP' => 'TEST_VALUE']))
)); ));
$dataStoreIntance = DataStoreMock::getDataStore('ID_VALUE'); $dataStoreIntance = DataStoreMock::getDataStore('ID_VALUE');

View File

@ -1,12 +1,31 @@
<?php <?php
include_once 'tests/__lib__/Mock.php'; include_once 'tests/__lib__/Mock.php';
include_once 'tests/__mocks__/BeanMock.php';
include_once 'tests/__mocks__/SettingMock.php';
include_once 'tests/__mocks__/RedBeanMock.php';
include_once 'models/MailTemplate.php'; include_once 'models/MailTemplate.php';
use RedBeanPHP\Facade as RedBean;
class MailTemplateTest extends PHPUnit_Framework_TestCase { class MailTemplateTest extends PHPUnit_Framework_TestCase {
protected function setUp() {
RedBean::initStubs();
Setting::initStubs();
RedBean::setStatics([
'findOne' => \Mock::stub()->returns($this->getMockTemplateBean())
]);
}
public function testGetTemplateShouldReturnSpecifiedTemplate() { public function testGetTemplateShouldReturnSpecifiedTemplate() {
$mailTemplate = MailTemplate::getTemplate(MailTemplate::USER_SIGNUP); $mailTemplate = MailTemplate::getTemplate(MailTemplate::USER_SIGNUP);
$this->assertEquals(MailTemplate::USER_SIGNUP, $mailTemplate->type); $this->assertEquals('TEST_TYPE', $mailTemplate->type);
$this->assertTrue(Redbean::get('findOne')->hasBeenCalledWithArgs('mailtemplate', 'type = :type AND language = :language', array(
':type' => 'USER_SIGNUP',
':language' => 'MOCK_SETTING_VALUE'
)));
} }
public function testCompilation() { public function testCompilation() {
@ -24,4 +43,14 @@ class MailTemplateTest extends PHPUnit_Framework_TestCase {
$this->assertEquals($result['subject'], 'Welcoming to cersei@opensupports.com'); $this->assertEquals($result['subject'], 'Welcoming to cersei@opensupports.com');
$this->assertEquals($result['body'], 'Welcome, Cersei Lannister to our team'); $this->assertEquals($result['body'], 'Welcome, Cersei Lannister to our team');
} }
private function getMockTemplateBean() {
$mailTemplateBean = new BeanMock();
$mailTemplateBean->type = 'TEST_TYPE';
$mailTemplateBean->body = 'Some body';
$mailTemplateBean->subject = 'Some subject';
$mailTemplateBean->language = 'en';
return $mailTemplateBean;
}
} }