From d6853b3a4bd8af73067fa0393463ff36701f1c32 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 4 Aug 2016 00:59:04 -0300 Subject: [PATCH] Ivan - Fix all list/beanInstance functionality --- server/controllers/system/init-settings.php | 15 ++ server/controllers/ticket/comment.php | 3 +- server/controllers/ticket/create.php | 21 ++- server/controllers/user/login.php | 6 +- server/controllers/user/recover-password.php | 2 +- server/data/ERRORS.php | 1 + server/index.php | 5 + server/libs/DataStoreList.php | 46 ++++++ server/libs/validations/dataStoreExists.php | 43 +++++ server/models/Comment.php | 1 - server/models/DataStore.php | 156 ++++++++++++------- server/models/Department.php | 12 ++ server/models/Setting.php | 4 + server/models/Ticket.php | 13 -- server/models/User.php | 16 +- server/tests/models/DataStoreTest.php | 5 +- 16 files changed, 263 insertions(+), 86 deletions(-) create mode 100644 server/libs/DataStoreList.php create mode 100644 server/libs/validations/dataStoreExists.php create mode 100644 server/models/Department.php diff --git a/server/controllers/system/init-settings.php b/server/controllers/system/init-settings.php index 578791b5..b17aca96 100644 --- a/server/controllers/system/init-settings.php +++ b/server/controllers/system/init-settings.php @@ -14,6 +14,7 @@ class InitSettingsController extends Controller { if (Setting::isTableEmpty()) { $this->storeGlobalSettings(); $this->storeMailTemplates(); + $this->storeMockedDepartments(); Response::respondSuccess(); } else { @@ -63,4 +64,18 @@ class InitSettingsController extends Controller { $setting->store(); } } + + private function storeMockedDepartments() { + $departments = [ + 'Tech Support', + 'Suggestions', + 'Sales and Subscriptions' + ]; + + foreach ($departments as $departmentName) { + $department = new Department(); + $department->name = $departmentName; + $department->store(); + } + } } \ No newline at end of file diff --git a/server/controllers/ticket/comment.php b/server/controllers/ticket/comment.php index f1a82231..1e1d632a 100644 --- a/server/controllers/ticket/comment.php +++ b/server/controllers/ticket/comment.php @@ -33,7 +33,8 @@ class CommentController extends Controller { )); $ticket = Ticket::getTicket($this->ticketId); - $ticket->addComment($comment); + $ticket->ownCommentList->add($comment); + //$comment->store(); $ticket->store(); } } \ No newline at end of file diff --git a/server/controllers/ticket/create.php b/server/controllers/ticket/create.php index 82722804..f66b815c 100644 --- a/server/controllers/ticket/create.php +++ b/server/controllers/ticket/create.php @@ -1,5 +1,6 @@ [ 'validation' => DataValidator::length(10, 500), 'error' => ERRORS::INVALID_CONTENT + ], + 'departmentId' => [ + 'validation' => DataValidator::dataStoreId('department'), + 'error' => ERRORS::INVALID_DEPARTMENT ] ] ]; @@ -39,22 +44,28 @@ class CreateController extends Controller { $this->language = Controller::request('language'); } - private function storeTicket() { + private function storeTicket() + { + $department = Department::getDataStore($this->departmentId); + $author = Controller::getLoggedUser(); + $ticket = new Ticket(); $ticket->setProperties(array( 'ticketId' => '', 'title' => $this->title, 'content' => $this->content, 'language' => $this->language, - 'department' => $this->departmentId, + 'author' => $author, + 'department' => $department, 'file' => '', 'date' => Date::getCurrentDate(), 'unread' => false, - 'closed' => false + 'closed' => false, )); + + $author->sharedTicketList->add($ticket); - $ticket->setAuthor(Controller::getLoggedUser()); - + $author->store(); $ticket->store(); } } diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index 0d00e257..b32e757e 100644 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -76,8 +76,8 @@ class LoginController extends Controller { $userId = Controller::request('userId'); if (!$sessionCookie->isNull() && $userId === $sessionCookie->user->id) { - $userInstance = new User($sessionCookie->user); - $sessionCookie->trash(); + $userInstance = $sessionCookie->user; + $sessionCookie->delete(); } } @@ -91,7 +91,7 @@ class LoginController extends Controller { $sessionCookie = new SessionCookie(); $sessionCookie->setProperties(array( - 'user' => $this->userInstance->getBeanInstance(), + 'user' => $this->userInstance, 'token' => $this->rememberToken, 'ip' => $_SERVER['REMOTE_ADDR'], 'creationDate' => date('d-m-Y (H:i:s)') diff --git a/server/controllers/user/recover-password.php b/server/controllers/user/recover-password.php index 519968c8..b455e16a 100644 --- a/server/controllers/user/recover-password.php +++ b/server/controllers/user/recover-password.php @@ -39,7 +39,7 @@ class RecoverPasswordController extends Controller { $user = User::getDataStore($this->email, 'email'); if($recoverPassword && $user) { - $recoverPassword->trash(); + $recoverPassword->delete(); $user->setProperties([ 'password' => Hashing::hashPassword($this->password) diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php index 0c01f73f..cd02d7c4 100644 --- a/server/data/ERRORS.php +++ b/server/data/ERRORS.php @@ -9,5 +9,6 @@ class ERRORS { const INVALID_PASSWORD = 'Invalid password'; const INVALID_NAME = 'Invalid name'; const INVALID_SETTING = 'Invalid setting'; + const INVALID_DEPARTMENT = 'Invalid department'; const INIT_SETTINGS_DONE = 'Settings already initialized'; } diff --git a/server/index.php b/server/index.php index 1e5151a0..5f9c18ee 100644 --- a/server/index.php +++ b/server/index.php @@ -5,6 +5,7 @@ require_once 'vendor/autoload.php'; // REDBEAN CONFIGURATION use RedBeanPHP\Facade as RedBean; RedBean::setup('mysql:host='. $mysql_host .';dbname=' . $mysql_database, $mysql_user, $mysql_password); +RedBean::setAutoResolve(true); // SLIM FRAMEWORK \Slim\Slim::registerAutoLoader(); @@ -16,6 +17,7 @@ include_once 'libs/ControllerGroup.php'; include_once 'libs/Hashing.php'; include_once 'libs/MailSender.php'; include_once 'libs/Date.php'; +include_once 'libs/DataStoreList.php'; // LOAD DATA spl_autoload_register(function ($class) { @@ -35,6 +37,9 @@ spl_autoload_register(function ($class) { } }); +//Load custom validations +include_once 'libs/validations/dataStoreExists.php'; + // LOAD CONTROLLERS foreach (glob('controllers/*.php') as $controller) { include_once $controller; diff --git a/server/libs/DataStoreList.php b/server/libs/DataStoreList.php new file mode 100644 index 00000000..1a6d1b93 --- /dev/null +++ b/server/libs/DataStoreList.php @@ -0,0 +1,46 @@ +add(new $type($bean)); + } + + return $dataStoreList; + } + + public function add(DataStore $dataStore) { + $this->list[] = $dataStore; + } + + public function remove(DataStore $dataStore) { + $dataStoreIndexInList = $this->getIndexInListOf($dataStore); + + unset($this->list[$dataStoreIndexInList]); + } + + public function toBeanList() { + $beanList = []; + + foreach($this->list as $item) { + $beanList[] = $item->getBeanInstance(); + } + + return $beanList; + } + + private function getIndexInListOf($dataStore) { + foreach ($this->list as $itemIdInList => $item) { + if ($item->id === $dataStore->id) { + return $itemIdInList; + } + } + + return -1; + } +} \ No newline at end of file diff --git a/server/libs/validations/dataStoreExists.php b/server/libs/validations/dataStoreExists.php new file mode 100644 index 00000000..56204275 --- /dev/null +++ b/server/libs/validations/dataStoreExists.php @@ -0,0 +1,43 @@ +isDataStoreNameValid($dataStoreName)) { + $this->dataStoreName = $dataStoreName; + } else { + throw new \Exception("Invalid DataStore: $dataStoreName"); + } + } + + public function validate($dataStoreId) { + $dataStore = null; + + switch ($this->dataStoreName) { + case 'user': + $dataStore = \User::getUser($dataStoreId); + break; + case 'ticket': + $dataStore = \Ticket::getTicket($dataStoreId); + break; + case 'department': + $dataStore = \Department::getDataStore($dataStoreId); + break; + } + + return !($dataStore instanceof \NullDataStore); + } + + private function isDataStoreNameValid($dataStoreName) { + return in_array($dataStoreName, [ + 'user', + 'ticket', + 'department' + ]); + } +} \ No newline at end of file diff --git a/server/models/Comment.php b/server/models/Comment.php index c5dfb3c5..1ff8ae86 100644 --- a/server/models/Comment.php +++ b/server/models/Comment.php @@ -7,7 +7,6 @@ class Comment extends DataStore { return array( 'content', 'file', - 'ticket', 'author', 'date' ); diff --git a/server/models/DataStore.php b/server/models/DataStore.php index 91c8750d..01e95404 100644 --- a/server/models/DataStore.php +++ b/server/models/DataStore.php @@ -3,6 +3,7 @@ use RedBeanPHP\Facade as RedBean; abstract class DataStore { protected $_bean; + protected $properties = []; public static function isTableEmpty() { return (RedBean::count(static::TABLE) === 0); @@ -16,55 +17,6 @@ abstract class DataStore { return ($bean) ? new static($bean) : new NullDataStore(); } - public function __construct($beanInstance = null) { - - if ($beanInstance) { - $this->_bean = $beanInstance; - } - else { - $this->_bean = RedBean::dispense(static::TABLE); - $defaultProperties = $this->getDefaultProps(); - - foreach ($defaultProperties as $PROP => $VALUE) { - $this->_bean[$PROP] = $VALUE; - } - } - } - - public function getDefaultProps() { - return []; - } - - public function delete() { - RedBean::trash($this->getBeanInstance()); - unset($this); - } - - public function getBeanInstance() { - return $this->_bean; - } - - public function setProperties($properties) { - foreach (static::getProps() as $PROP) { - if(array_key_exists($PROP, $properties)) { - $this->_bean[$PROP] = $properties[$PROP]; - } - } - } - - public function __get($name) { - if ($this->_bean[$name]) { - return $this->_bean[$name]; - } - else { - return null; - } - } - - public function store() { - return RedBean::store($this->_bean); - } - private static function validateProp($propToValidate) { $validProp = false; @@ -77,11 +29,111 @@ abstract class DataStore { return ($validProp) ? $propToValidate : 'id'; } - public function trash() { - RedBean::trash($this->_bean); + public function __construct($beanInstance = null) { + if ($beanInstance) { + $this->setBean($beanInstance); + } else { + $this->setBean(RedBean::dispense(static::TABLE)); + $this->setProperties($this->getDefaultProps()); + } } - + + public function getDefaultProps() { + return []; + } + + public function setProperties($properties) { + foreach (static::getProps() as $PROP) { + if(array_key_exists($PROP, $properties)) { + $this->properties[$PROP] = $properties[$PROP]; + } + } + } + + public function __set($prop, $value) { + if (in_array($prop, static::getProps())) { + $this->properties[$prop] = $value; + } else { + throw new Exception("Invalid prop: $prop"); + } + } + + public function &__get($name) { + if (!array_key_exists($name, $this->properties) || !$this->properties[$name]) { + $this->properties[$name] = $this->parseBeanProp($name); + } + + if ($name !== 'id') { + $property =& $this->properties[$name]; + } else { + $property = $this->_bean->id; + } + + return $property; + } + + private function setBean($beanInstance) { + $this->_bean = $beanInstance; + } + + private function parseBeanProp($prop) { + $parsedProp = $this->_bean[$prop]; + + if (strpos($prop, 'List')) { + $parsedProp = DataStoreList::getList($this->getListType($prop), $parsedProp); + } else if ($parsedProp instanceof \RedBeanPHP\OODBBean) { + $beanType = ucfirst($parsedProp->getPropertiesAndType()[1]); + + $parsedProp = new $beanType($parsedProp); + + } + + return $parsedProp; + } + + public function store() { + + return RedBean::store($this->getBeanInstance()); + } + + public function delete() { + RedBean::trash($this->getBeanInstance()); + unset($this); + } + + public function getBeanInstance() { + $this->updateBeanProperties(); + + return $this->_bean; + } + public function isNull() { return false; } + + private function updateBeanProperties() { + foreach ($this->properties as $key => $prop) { + $this->updateBeanProp($key, $prop); + } + } + + private function updateBeanProp($key, $value) { + if ($value instanceof DataStoreList) { + $this->_bean[$key] = $value->toBeanList(); + } else if ($value instanceof DataStore) { + $this->_bean[$key] = $value->getBeanInstance(); + } else { + $this->_bean[$key] = $value; + } + } + + private function getListType($listName) { + $listType = $listName; + + $listType = str_replace('List', '', $listType); + $listType = str_replace('shared', '', $listType); + $listType = str_replace('own', '', $listType); + + return $listType; + } } diff --git a/server/models/Department.php b/server/models/Department.php new file mode 100644 index 00000000..cdfae8b5 --- /dev/null +++ b/server/models/Department.php @@ -0,0 +1,12 @@ +value; + } } \ No newline at end of file diff --git a/server/models/Ticket.php b/server/models/Ticket.php index 8d1a8fe8..ff20334a 100644 --- a/server/models/Ticket.php +++ b/server/models/Ticket.php @@ -33,19 +33,6 @@ class Ticket extends DataStore { ); } - public function setAuthor(User $user) { - $this->author = $user; - $this->author->addTicket($this); - - $this->setProperties(array( - 'author' => $this->author->getBeanInstance() - )); - } - - public function addComment(Comment $comment) { - $this->getBeanInstance()->ownCommentList[] = $comment->getBeanInstance(); - } - public function store() { parent::store(); diff --git a/server/models/User.php b/server/models/User.php index 186091c0..eefbc4c5 100644 --- a/server/models/User.php +++ b/server/models/User.php @@ -11,20 +11,20 @@ class User extends DataStore { } public static function getProps() { - return array( + return [ 'email', 'password', 'name', - 'verificationToken' - ); + 'admin', + 'sharedTicketList', + 'verificationToken', + ]; } public function getDefaultProps() { - return array(); - } - - public function addTicket(Ticket $ticket) { - $this->getBeanInstance()->sharedTicketList[] = $ticket->getBeanInstance(); + return [ + 'admin' => 0 + ]; } public static function getUser($value, $property = 'id') { diff --git a/server/tests/models/DataStoreTest.php b/server/tests/models/DataStoreTest.php index 608ea9a3..a4aa7e63 100644 --- a/server/tests/models/DataStoreTest.php +++ b/server/tests/models/DataStoreTest.php @@ -35,6 +35,7 @@ class DataStoreTest extends PHPUnit_Framework_TestCase { } public function testContructor() { + $this->instance->store(); $newInstance = new DataStoreMock($this->instance->getBeanInstance()); $this->assertEquals($newInstance->prop1, 0); @@ -58,12 +59,12 @@ class DataStoreTest extends PHPUnit_Framework_TestCase { public function testGetDataStore() { RedBean::setStatics(array( - 'findOne' => \Mock::stub()->returns(new BeanMock(['TEST_PROP' => 'TEST_VALUE'])) + 'findOne' => \Mock::stub()->returns(new BeanMock(['prop1' => 'TEST_VALUE'])) )); $dataStoreIntance = DataStoreMock::getDataStore('ID_VALUE'); - $this->assertEquals($dataStoreIntance->TEST_PROP, 'TEST_VALUE'); + $this->assertEquals($dataStoreIntance->prop1, 'TEST_VALUE'); $this->assertTrue(RedBean::get('findOne')->hasBeenCalledWithArgs( 'MOCK_TABLE',