From 38c33fa41391ef4afa2dfcd3ca30609478733767 Mon Sep 17 00:00:00 2001 From: Juan Menendez Date: Wed, 1 Apr 2015 14:53:43 +0200 Subject: [PATCH] #116: Moved PHPList logic to User model for the events Delete and Save. Removed it from AdminController and ProfileController. --- TGD/protected/config/config.sample.php | 2 + TGD/protected/controllers/ApiController.php | 15 +- TGD/protected/extensions/PHPList.php | 213 +++++++++++------- .../user/controllers/AdminController.php | 111 ++------- .../user/controllers/ProfileController.php | 12 +- TGD/protected/modules/user/models/User.php | 115 +++++++++- 6 files changed, 274 insertions(+), 194 deletions(-) diff --git a/TGD/protected/config/config.sample.php b/TGD/protected/config/config.sample.php index 3882cb7..daa77ad 100644 --- a/TGD/protected/config/config.sample.php +++ b/TGD/protected/config/config.sample.php @@ -46,6 +46,8 @@ const PHPLIST_APPLIED_LIST = 0; const PHPLIST_PRE_ACCEPTED_LIST = 0; const PHPLIST_ACCEPTED_LIST = 0; +const PHPLIST_PRE_ACCEPTED_OPTED_OUT_LIST = 0; +const PHPLIST_ACCEPTED_OPTED_OUT_LIST = 0; const PHPLIST_DENIED_LIST = 0; const PHPLIST_LEFT_LIST = 0; const PHPLIST_EXPELLED_LIST = 0; diff --git a/TGD/protected/controllers/ApiController.php b/TGD/protected/controllers/ApiController.php index 3d90f9f..36e4d21 100644 --- a/TGD/protected/controllers/ApiController.php +++ b/TGD/protected/controllers/ApiController.php @@ -590,23 +590,14 @@ public function actionAddToPHPList(){ $phplist = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); $result = $phplist->addUserToList($email, $list); - if($result > 0){ + if($result){ $result_data = array( 'result'=>'success', 'message'=>'The user with email ' . $email . ' has been added to the list ' . $list . '.' ); }else{ - $result_data = array('result'=>'fail'); - if($result == -1){ - $result_data['message'] = 'User with email ' . $email . ' couldn\'t be created.'; - }else if($result == -2){ - $result_data['message'] = 'There\'s no list called ' . $list . '.'; - }else if($result == -3){ - $result_data['message'] = 'User with email ' . $email . ' is already in list ' . $list . '.'; - }else if($result === false){ - $result_data['message'] = 'There has been an error processing the request.'; - } - + $result_data = array('result'=>'fail', + 'message' => 'There has been an error processing the request.'); } $this->_sendResponse(200, CJSON::encode($result_data), 'application/json'); diff --git a/TGD/protected/extensions/PHPList.php b/TGD/protected/extensions/PHPList.php index 9ea4301..a611bc6 100644 --- a/TGD/protected/extensions/PHPList.php +++ b/TGD/protected/extensions/PHPList.php @@ -70,10 +70,17 @@ private function _getConnection(){ return $dbh; } + /** + * Get the user id + * @param string $email User email address + * @return mixed User id or false if not found. + */ private function _getUserId($email){ + + $db = $this->_db; $sql = "SELECT * FROM phplist_user_user WHERE email = :email"; + try{ - $db = $this->_db; $stmt = $db->prepare($sql); $stmt->bindParam("email", $email); $stmt->execute(); @@ -83,7 +90,7 @@ private function _getUserId($email){ $row = $stmt->fetch(); return $row['id']; }else{ - return -1; + return false; } }catch(PDOException $e){ return false; @@ -91,49 +98,53 @@ private function _getUserId($email){ } /** - * Finds the Id of on existing list, givent its name. - * @param string $list The list name. - * @return mixed The list id if it exists, false if it doesn't and - * -1 in case of an error processing the request. + * Finds the Id of the lists a user is in. + * @param int $userId The user id. + * @return array The list ids + * false in case of an error processing the request. */ - private function _getListId($list){ + private function _getUserLists($userId){ + + $db = $this->_db; + $list = array(); + $sql = "SELECT * FROM phplist_listuser WHERE userid = :id"; - $sql = "SELECT * FROM phplist_list WHERE lower(name) = :list"; try{ - $db = $this->_db; $stmt = $db->prepare($sql); - $list = strtolower($list); - $stmt->bindParam("list", $list); + $stmt->bindParam("id", $userId); $stmt->execute(); + $rowCount = $stmt->rowCount(); - if($stmt->rowCount() > 0){ - $row = $stmt->fetch(); - return $row['id']; - - }else{ - return -1; + while($row = $stmt->fetch()){ + $list[] = $row['listid']; } + + return sizeof($list)? $list : false; + }catch(PDOException $e){ return false; } } + /** * Creates a PHPList user with a set of provided properties. If a user with the given * email address already exists, it returns her id. * @param array $data Properties with which the user will be created. - * @return int The user id or -1 if there was an error processing the request. + * @return int The user id + * false otherwise. */ private function _createUser($data){ - - $id = $this->_getUserId($data['email']); + + $db = $this->_db; + $userId = $this->_getUserId($data['email']); - if($id == -1){ + + if($userId === false){ // User doesn't exist. Create it. $sql = "INSERT INTO phplist_user_user (email, confirmed, htmlemail, rssfrequency, password, passwordchanged, disabled, entered, uniqid) VALUES (:email, :confirmed, :htmlemail, :rssfrequency, :password, now(), :disabled, now(), :uniqid);"; try { $uniqid = md5(uniqid(mt_rand())); - $db = $this->_db; $stmt = $db->prepare($sql); $stmt->bindParam("email", $data['email']); $stmt->bindParam("confirmed", $data['confirmed']); @@ -146,125 +157,163 @@ private function _createUser($data){ // Assign id of recently created user. if($stmt->rowCount() > 0){ - $id = $db->lastInsertId(); + return $db->lastInsertId(); }else{ - $id = -1; + return false; } } catch(PDOException $e) { return false; } } - return $id; + return $userId; } - + /** - * Adds a user to a list. - * @param string $email User email. - * @param string $list List name. - * @return mixed false if there was an exception thrown, - * 1 if the user was added successfully - * -1 if user wasn't found, - * -2 if list wasn't found, - * -3 if user already was in the list. + * Deletes a PHPList user. + * @param int $id User id. + * @return int The amount of deleted users + * false if there was an error processing the request. */ - public function addUserToList( $email, $list ){ + private function _deleteUser($userId){ - $user_id = $this->_createUser(array('email' =>$email, 'confirmed'=>1)); - $list_id = is_int($list)? $list : (ctype_digit($list) ? intval($list) : $this->_getListId($list)); + $db = $this->_db; + $sql = "DELETE FROM phplist_user_user WHERE id=:id;"; - if( $user_id && $list_id === false ) { + try { + $stmt = $db->prepare($sql); + $stmt->bindParam("id", $userId); + $stmt->execute(); + return $stmt->rowCount() > 0; + + } catch(PDOException $e) { return false; } + } + /** + * Deletes user from some lists + * @param int $user_id User Id. + * @param array $lists Lists to remove the user from. + * @return boolean True if no error was found, false if there was. + */ + private function _deleteUserFromList($userId, $listId){ + + $db = $this->_db; - if($list_id < 0) return -2; - if($user_id < 0) return -1; - - $sql = "INSERT INTO phplist_listuser (userid, listid, entered, modified) VALUES (:user_id, :list_id, now(), now());"; + $sql = "DELETE FROM phplist_listuser WHERE userid=:user_id AND listid=:list_id;"; try { - $db = $this->_db; $stmt = $db->prepare($sql); - $stmt->bindParam("user_id", $user_id ); - $stmt->bindParam("list_id", $list_id ); + $stmt->bindParam("user_id", $userId ); + $stmt->bindParam("list_id", $listId ); $stmt->execute(); - return $stmt->rowCount(); + return $stmt->rowCount() >= 0; } catch(PDOException $e) { - if ($e->getCode() == '23000'){ - return -3; - } - return false; - } + } } /** - * Removes a user from a list. - * @param string $email User email. - * @param string $list List name. - * @return mixed false if there was an exception thrown, - * -1 if user wasn't found, - * -2 if list wasn't found. + * Delete user. + * @param string $email User email. + * @return boolean */ - public function removeUserFromList( $email, $list ){ + public function deleteUser($email){ + $userId = $this->_getUserId($email); + if(!$userId){ + return true; + } + $lists = $this->_getUserLists($userId); + + $listsDeleted = true; + foreach($lists as $listId){ + $listsDeleted = $listsDeleted && $this->_deleteUserFromList($userId, $listId); + } - $user_id = $this->_createUser(array('email' =>$email, 'confirmed'=>1)); - $list_id = is_int($list)? $list : (ctype_digit($list) ? intval($list) : $this->_getListId($list)); + return $this->_deleteUser($userId); + } + /** + * Adds a user to a list. + * @param string $email User email. + * @param string $list List id. + * @return boolean false if fail, + * true if the user was added successfully + */ + public function addUserToList( $email, $listId ){ - if( $user_id && $list_id === false ) { + $db = $this->_db; + $userId = $this->_createUser(array('email' =>$email, 'confirmed'=>1)); + if( $userId === false ) { return false; } - - if($list_id < 0) return -2; - if($user_id < 0) return -1; - - $sql = "DELETE FROM phplist_listuser WHERE userid=:user_id AND listid=:list_id;"; + $sql = "INSERT INTO phplist_listuser (userid, listid, entered, modified) VALUES (:user_id, :list_id, now(), now());"; try { - $db = $this->_db; $stmt = $db->prepare($sql); - $stmt->bindParam("user_id", $user_id ); - $stmt->bindParam("list_id", $list_id ); + $stmt->bindParam("user_id", $userId ); + $stmt->bindParam("list_id", $listId ); $stmt->execute(); - - return $stmt->rowCount(); + return $stmt->rowCount() > 0; } catch(PDOException $e) { + if ($e->getCode() == '23000'){ + return true; + } return false; } } /** * Removes a user from a list. - * @param string $email User email. - * @param int $from List origin. - * @param int $to List destination. - * @return mixed false if there was an exception thrown, - * 1 if the user list was updated. - * 0 if no user list was updated. + * @param string $email User email. + * @param string $list List name. + * @return mixed true if it worked + * false if there was an exception thrown, */ - public function moveUser( $email, $from, $to ){ + public function deleteUserFromList( $email, $listId ){ - $user_id = $this->_createUser(array('email' =>$email, 'confirmed'=>1)); + $userId = $this->_getUserId($email); + if(!$userId){ + // there's no user with that email. Fair enough. Return OK. + return true; + } - if( $user_id === false ) { + return $this->_deleteUserFromList($userId, $listId); + } + + /** + * Moves a user from a list to another. + * @param string $email User email. + * @param int $from List origin. + * @param int $to List destination. + * @return mixed true if it worked. + * false if there's not such user, + * no user-list combination was found + * or there was an exception thrown, + */ + public function moveUser( $email, $from, $to ){ + + $db = $this->_db; + $user_id = $this->_getUserId($email); + + if(!$user_id) { return false; } $sql = "UPDATE phplist_listuser SET listid=:to_list_id WHERE userid=:user_id AND listid=:from_list_id;"; try { - $db = $this->_db; $stmt = $db->prepare($sql); $stmt->bindParam("user_id", $user_id ); $stmt->bindParam("from_list_id", $from ); $stmt->bindParam("to_list_id", $to ); $stmt->execute(); - return $stmt->rowCount(); + return $stmt->rowCount() > 0; + } catch(PDOException $e) { echo $e->getMessage(); return false; diff --git a/TGD/protected/modules/user/controllers/AdminController.php b/TGD/protected/modules/user/controllers/AdminController.php index e70c91e..68aa324 100644 --- a/TGD/protected/modules/user/controllers/AdminController.php +++ b/TGD/protected/modules/user/controllers/AdminController.php @@ -14,19 +14,19 @@ class AdminController extends Controller private $_model; - private $statusToList = array( - User::STATUS_APPLIED => PHPLIST_APPLIED_LIST, - User::STATUS_PRE_ACCEPTED => PHPLIST_PRE_ACCEPTED_LIST, - User::STATUS_ACCEPTED => PHPLIST_ACCEPTED_LIST, - User::STATUS_DENIED => PHPLIST_DENIED_LIST, - User::STATUS_LEFT => PHPLIST_LEFT_LIST, - User::STATUS_EXPELLED => PHPLIST_EXPELLED_LIST, - ); - - private $statusToListNotification = array( - User::STATUS_PRE_ACCEPTED => array(24, 36), - User::STATUS_ACCEPTED => array(35, 25), - ); + // private $statusToList = array( + // User::STATUS_APPLIED => PHPLIST_APPLIED_LIST, + // User::STATUS_PRE_ACCEPTED => PHPLIST_PRE_ACCEPTED_LIST, + // User::STATUS_ACCEPTED => PHPLIST_ACCEPTED_LIST, + // User::STATUS_DENIED => PHPLIST_DENIED_LIST, + // User::STATUS_LEFT => PHPLIST_LEFT_LIST, + // User::STATUS_EXPELLED => PHPLIST_EXPELLED_LIST, + // ); + + // private $statusToListNotification = array( + // User::STATUS_PRE_ACCEPTED => array(24, 36), + // User::STATUS_ACCEPTED => array(35, 25), + // ); /** * @return array action filters @@ -202,88 +202,13 @@ public function actionUpdate() } /* END UPLOAD FILE */ - - $phplist = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); - $email = $model->email; - if ($previous_status != $new_status){ - -// $phplist = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); -// -// $email = $model->email; - $to_list = $this->statusToList[$new_status]; - $from_list = $this->statusToList[$previous_status]; - - //if notification preferences: subscribe and phplist segments are 24 or 25. Issue:Add more membership details #20 - if(($to_list != PHPLIST_PRE_ACCEPTED_LIST && $to_list != PHPLIST_ACCEPTED_LIST) || - (($to_list == PHPLIST_PRE_ACCEPTED_LIST || $to_list == PHPLIST_ACCEPTED_LIST) && $model->notification_preferences)) - { - - // There's a special case when the user changes from status Applied to status Pre-accepted. - // In this case, the user doesn't move from one list to another, but instead is added to the list. - if ($previous_status == User::STATUS_APPLIED && $new_status == User::STATUS_PRE_ACCEPTED) { - // send email - Yii::app()->getModule('user')->sendApplicationApproval($model); - // add user to list - $result = $phplist->addUserToList($email, $to_list); - $phplist->addUserToList($email, 36); - - if ($result == 1) { - Yii::app()->user->setFlash('userAdmin', "The user has been added to PHPList pre-accepted list."); - } - - } // if both of the lists assigned to each status, exists in config. - - elseif ($from_list * $to_list > 0) { - // move user between lists - $phplist->removeUserFromList($email, $from_list); - $result = $phplist->addUserToList($email, $to_list); - if($to_list == PHPLIST_PRE_ACCEPTED_LIST){ - $phplist->removeUserFromList($email, 35); - $phplist->addUserToList($email, 36); - }elseif($to_list == PHPLIST_ACCEPTED_LIST){ - $phplist->removeUserFromList($email, 35); - $phplist->addUserToList($email, 35); - } - - if ($result == 1) { - Yii::app()->user->setFlash('userAdmin', "The user has been moved from list {$from_list} to list {$to_list} ."); - } - } elseif ($to_list == 0) { - // delete user from lists - $result = $phplist->removeUserFromList($email, $from_list); - if($to_list == PHPLIST_PRE_ACCEPTED_LIST){ - $phplist->removeUserFromList($email, 35); - }elseif($to_list == PHPLIST_ACCEPTED_LIST){ - $phplist->removeUserFromList($email, 36); - } - } - }else{ - foreach($this->statusToListNotification as $list){ - foreach($list as $list_id){ - $phplist->removeUserFromList($email, $list_id); - } - } - Yii::app()->user->setFlash('userAdmin', "The user has been removed from PHPList pre-accepted and accepted list."); - } - - }elseif($model->notification_preferences){ - if(array_key_exists($model->status, $this->statusToListNotification)){ - if(!empty($this->statusToListNotification[$model->status])){ - foreach($this->statusToListNotification[$model->status] as $list){ - $phplist->addUserToList($email, $list); - } - Yii::app()->user->setFlash('userAdmin', "The user has been added to PHPList pre-accepted or accepted list."); - } - } - }else{ - foreach($this->statusToListNotification as $list){ - foreach($list as $list_id){ - $phplist->removeUserFromList($email, $list_id); - } - } - Yii::app()->user->setFlash('userAdmin', "The user has been removed from PHPList pre-accepted and accepted list."); + if ($previous_status == User::STATUS_APPLIED && $new_status == User::STATUS_PRE_ACCEPTED) { + // send email + Yii::app()->getModule('user')->sendApplicationApproval($model); + + } } $this->redirect(array('view','id'=>$model->id)); diff --git a/TGD/protected/modules/user/controllers/ProfileController.php b/TGD/protected/modules/user/controllers/ProfileController.php index ae73b8a..5b6638f 100755 --- a/TGD/protected/modules/user/controllers/ProfileController.php +++ b/TGD/protected/modules/user/controllers/ProfileController.php @@ -10,10 +10,10 @@ class ProfileController extends Controller */ private $_model; - private $statusToList = array( - User::STATUS_PRE_ACCEPTED => array(24, 36), - User::STATUS_ACCEPTED => array(35, 25), - ); + // private $statusToList = array( + // User::STATUS_PRE_ACCEPTED => array(24, 36), + // User::STATUS_ACCEPTED => array(35, 25), + // ); /** * Shows a particular model. @@ -124,7 +124,7 @@ public function actionProfile() } /* END UPLOAD FILE */ - /* START PHPList */ + /* START PHPList $phplist = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); $email = $user->email; @@ -143,7 +143,7 @@ public function actionProfile() } } } - /* END PHPList */ + END PHPList */ } Yii::app()->user->username = $user->username; $success="Changes have been made successfully"; diff --git a/TGD/protected/modules/user/models/User.php b/TGD/protected/modules/user/models/User.php index 595b1c3..5b50024 100644 --- a/TGD/protected/modules/user/models/User.php +++ b/TGD/protected/modules/user/models/User.php @@ -14,6 +14,18 @@ class User extends CActiveRecord public $image; + // this is for PHPList management + private $_old_data = array(); + private $_new_data = array(); + private $_statusToList = array( + self::STATUS_APPLIED => PHPLIST_APPLIED_LIST, + self::STATUS_PRE_ACCEPTED => array(PHPLIST_PRE_ACCEPTED_LIST, PHPLIST_PRE_ACCEPTED_OPTED_OUT_LIST), + self::STATUS_ACCEPTED => array(PHPLIST_ACCEPTED_LIST, PHPLIST_ACCEPTED_OPTED_OUT_LIST), + self::STATUS_DENIED => PHPLIST_DENIED_LIST, + self::STATUS_LEFT => PHPLIST_LEFT_LIST, + self::STATUS_EXPELLED => PHPLIST_EXPELLED_LIST, + ); + //TODO: Delete for next version (backward compatibility) //const STATUS_BANED=-1; @@ -266,6 +278,87 @@ public function afterSave() { return parent::afterSave(); } */ + + public function afterDelete() { + + $this->_deleteFromPHPLists($this->email); + + return parent::afterDelete(); + } + + public function afterSave() { + + $this->_new_data['status'] = $this->status; + $this->_new_data['notification_preferences'] = $this->notification_preferences; + + $this->_managePHPLists(); + + return parent::afterSave(); + } + + private function _deleteFromPHPLists($userEmail, $phpList = null){ + if($phpList == null){ + $phpList = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); + } + + $phpList->deleteUser($this->email); + } + + private function _managePHPLists(){ + $phplist = new PHPList(PHPLIST_HOST, PHPLIST_DB, PHPLIST_LOGIN, PHPLIST_PASSWORD); + $added = false; + + // check change in notification status + if($this->_old_data['notification_preferences'] != $this->_new_data['notification_preferences']){ + + // if the user has opted-in + if($this->_new_data['notification_preferences']){ + // add to list depending on his new status + $lists = $this->_statusToList[$this->_new_data['status']]; + $lists = (is_int($lists)) ? array($lists) : $lists; + foreach($lists as $listId){ + if($listId > 0){ + $added = $added && $phplist->addUserToList($this->email, $listId); + } + } + } + // if the user has opted-out + else{ + // remove user + $this->_deleteFromPHPLists($this->email, $phplist); + } + } + + // check for a change in status + if($this->_new_data['notification_preferences'] && ($this->_old_data['status'] != $this->_new_data['status'])){ + // add user to list if it wasn't added in the previous step + + if(!$added){ + $lists = $this->_statusToList[$this->_new_data['status']]; + $lists = (is_int($lists)) ? array($lists) : $lists; + foreach($lists as $listId){ + if($listId > 0){ + $phplist->addUserToList($this->email, $listId); + } + } + } + + // remove from old list if necessary + if($this->_old_data['status'] == null) { + // when User is saved after creation, there's no old status. + // There's no need to continue. + return; + } + + $lists = $this->_statusToList[$this->_old_data['status']]; + $lists = (is_int($lists)) ? array($lists) : $lists; + foreach($lists as $listId){ + if($listId > 0){ + $phplist->deleteUserFromList($this->email, $listId); + } + } + } + } public function beforeSave() { @@ -273,5 +366,25 @@ public function beforeSave() { return parent::beforeSave(); } - + + public function afterFind() { + + // initialize old and new data to the same values + $this->_old_data['status'] = $this->status; + $this->_old_data['notification_preferences'] = $this->notification_preferences; + $this->_new_data['status'] = $this->status; + $this->_new_data['notification_preferences'] = $this->notification_preferences; + + return parent::afterFind(); + } + + public function afterConstruct() { + // initialize old and new data to the same values + $this->_old_data['status'] = null; + $this->_old_data['notification_preferences'] = null; + $this->_new_data['status'] = null; + $this->_new_data['notification_preferences'] = null; + + return parent::afterConstruct(); + } } \ No newline at end of file