/** * * Generates HTML with drop-down roles menu * and a Shred button if current Viewer has necessary * permissions * * @param Registry $Registry * @param User $User user whose profile is being viewed now * @return string html fragment with Form and button */ public static function getHtml(Registry $Registry, User $User) { $oACL = $Registry->Acl; $options = ''; $shredButton = ''; $token = ''; $uid = $User->getUid(); $role = $Registry->Viewer->getRoleId(); d('role: ' . $role); if ($oACL->isAllowed($role, null, 'change_user_role')) { d('change_user_role is allowed'); $userRole = $User->getRoleId(); $roles = $oACL->getRegisteredRoles(); $token = Form::generateToken(); foreach ($roles as $roleName => $val) { $selected = $roleName === $userRole ? ' selected' : ''; $options .= "\n" . vsprintf('<option value="%1$s"%2$s>%1$s</option>', array($roleName, $selected)); } } if ($oACL->isAllowed($role, null, 'shred_user')) { d('getting shred button'); $shredButton = '<div class="fl cb"><input type="button" class="ajax btn_shred rounded4" value="@@Shred User@@" id="shred' . $uid . '"></div>'; } if (empty($options) && empty($shredButton)) { return ''; } return \tplSelectrole::parse(array($token, $uid, $options, $shredButton), false); }
/** * Parse the avatar file in $tempPath, * by creating small square image from it, * save into file system and then add path to new avatar * in User object as 'avatar' element * * * @param User $User * @param unknown_type $tempPath * @throws \Lampcms\Exception * * @return object $this */ public function addAvatar(User $User, $tempPath) { d('$tempPath: ' . $tempPath); if (empty($tempPath)) { d('no avatar to add'); return $this; } $size = $this->Registry->Ini->AVATAR_SQUARE_SIZE; $avatarDir = LAMPCMS_DATA_DIR . 'img' . DS . 'avatar' . DS . 'sqr' . DS; d('$avatarDir: ' . $avatarDir); $savePath = Path::prepare($User->getUid(), $avatarDir); d('$savePath: ' . $savePath); /** * Create avatar and save it * with compression level of 80% (small compression) */ //try{ $ImgParser = \Lampcms\Image\Editor::factory($this->Registry)->loadImage($tempPath)->makeSquare($size); $savePath .= $ImgParser->getExtension(); $ImgParser->save($avatarDir . $savePath, null, 80); d('avatar saved to ' . $savePath); //} catch(\Lampcms\ImageException $e){ //e('ImageException caught in: '.$e->getFile().' on line: '.$e->getLine().' error: '.$e->getMessage()); //throw new \Lampcms\Exception('Unable to process your avatar image at this time'); //} /** * Now remove tempPath file */ @\unlink($tempPath); /** * Now add the path to avatar * to user object * save() is not invoked on User object here! * Either rely on auto-save (may not work in case User is * actually the Viewer object) or call save() * from a function that invoked this method */ $User['avatar'] = $savePath; return $this; }
/** * If User has permission to upload images * based on user group and reputation * and if Image upload is not disabled in !config.ini * by the way of setting IMAGE_UPLOAD_FILE_SIZE to 0 * then return the value of IMAGE_UPLOAD_FILE_SIZE * OR false if user should not be allowed to upload image * * @static * * @param \Lampcms\Registry $Registry * @param \Lampcms\User $User * * @throws \Lampcms\AccessException is User group is not allowed to upload images * or if user does not have enough reputation to upload images * * @return mixed false | int max upload size in Megabytes */ public static function getMaxFileSize(\Lampcms\Registry $Registry, \Lampcms\User $User) { $ImgUploadOptions = $Registry->Ini->getSection('EDITOR'); $maxSize = $ImgUploadOptions['IMAGE_UPLOAD_FILE_SIZE']; if (empty($maxSize)) { throw new AccessException('@@Image upload is disabled by administrator@@'); } $Acl = $Registry->Acl; if (!$Acl->isAllowed($User->getRoleId(), null, 'upload_image')) { throw new AccessException('@@You do not have permissions to upload images@@'); } $minReputation = (int) $ImgUploadOptions['IMAGE_UPLOAD_MIN_REPUTATION']; $rep = $User->getReputation(); if ($rep < $minReputation) { throw new AccessException('@@You do not have enough reputation points to upload images@@'); } return $maxSize; }
/** * Increase or decrease owner's profit point amount * after his question or answer receives a vote * * @return object $this */ protected function setOwnerProfitPoint() { $uid = $this->Resource->getOwnerId(); d('uid of resource owner: ' . $uid); /** * Now need to calculate points * */ try { \Lampcms\User::factory($this->Registry)->by_id($uid)->setProfitPoint($this->calculatePoints())->save(); } catch (\Exception $e) { e($e->getMessage() . ' in file: ' . $e->getFile() . ' on line: ' . $e->getLine()); } return $this; }
/** * Logic: For guests dont check question owner id * For others: insert into QUESTION_VIEWS first as a way * to test for duplicates. * Duplicates are: same uid and same qid * If no duplicate then also increase count of views for this * question * * @todo try to run this as post-echo method via runLater * callback. This is not really resource intensive, but still... * it checks for duplicate, checks viewer ID, etc... * This also runs on every page view, and also since we use fsync when * updating via MongoDoc object, it does require disk write. * * * @return object $this */ public function increaseViews(\Lampcms\User $Viewer, $inc = 1) { if (!\is_int($inc)) { throw new \InvalidArgumentException('Param $inc must be an integer. was: ' . gettype($inc)); } /** * @todo Don't count question owner view * For this we must be able to get Viewer from Registry * * Filter out duplicate views */ $viewerId = $Viewer->getUid(); /** * If guest, then there * will be a problem if we at least don't check * for same session_id */ $viewerId = 0 === $viewerId ? session_id() : $viewerId; $ownerID = $this->offsetGet('i_uid'); d('$viewerId: ' . $viewerId . ' $ownerID: ' . $ownerID); if ($viewerId === $ownerID) { d('viewing own question'); return $this; } $iViews = $this->offsetGet('i_views'); /** * If this is the first view, we will cheat a little * and set the views to 2 * There will never be just 1 view, and this way we don't * have to worry about the plural suffix */ if (0 === $iViews && 1 === $inc) { $inc = 2; } $collViews = $this->getRegistry()->Mongo->QUESTION_VIEWS; $collViews->ensureIndex(array('uid' => 1, 'qid' => 1), array('unique' => true)); $qid = (int) $this->offsetGet('_id'); try { $collViews->insert(array('qid' => $qid, 'uid' => $viewerId, 'i_ts' => time()), array('safe' => true)); parent::offsetSet('i_views', $iViews + (int) $inc); /** * If new value is NOT 1 then set * vw_s (plural suffix) to 's' otherwise * must set to empty string because * by default it's already set to 's' */ $this->offsetSet('vw_s', 's'); } catch (\MongoException $e) { d('duplicate view for qid ' . $qid . ' uid: ' . $viewerId); } return $this; }
/** * Increase answer count * for question. * Also set Last Answerer details * and add Answerer User to list * of Question contributors * (this is for the dot-folders feature) * * The increaseAnswerCount will also update * the last modified timestamp for question * * @return object $this */ protected function updateQuestion() { d('cp'); $uid = $this->Resource->getOwnerId(); d('uid of answer: ' . $uid); $User = \Lampcms\User::userFactory($this->Registry)->by_id($uid); d('$User id: ' . $User->getUid()); $this->Question->updateAnswerCount(); $this->Question->addContributor($User); $this->Question->setLatestAnswer($User, $this->Resource); $this->Question->touch(); $this->Question->save(); return $this; }
/** * Create $this->User object * that represents User whose profile * is being viewed currently * * * @throws \Lampcms\Lampcms404Exception * @return object $this */ protected function getUser() { $uid = $this->Router->getSegment($this->uidSegment, 'i'); $a = $this->Registry->Mongo->USERS->findOne(array('_id' => $uid)); if (empty($a)) { throw new \Lampcms\Lampcms404Exception('@@User not found@@'); } $this->User = User::userFactory($this->Registry, $a); $this->aPageVars['title'] = $this->User->getDisplayName(); return $this; }
/** * * Adds a_edited array of data to Question * * @param User $user * @param string $reason reason for editing * * @return object $this */ public function setEdited(User $user, $reason = '') { if (!empty($reason)) { $reason = \strip_tags((string) $reason); } $aEdited = $this->offsetGet('a_edited'); if (empty($aEdited) || !is_array($aEdited)) { $aEdited = array(); } $aEdited[] = array('username' => $user->getDisplayName(), 'i_uid' => $user->getUid(), 'av' => $user->getAvatarSrc(), 'reason' => $reason, 'i_ts' => time(), 'hts' => date('F j, Y g:i a T')); parent::offsetSet('a_edited', $aEdited); return $this; }
/** * Decrease the profit point amount of user who * owns the old answer * * @todo check current score and make sure * it will not become negative after we deduct * some points * * @return object $this */ protected function updateOldAnswerer() { if (!empty($this->aOldAnswer)) { $uid = $this->aOldAnswer['i_uid']; if (!empty($uid)) { try { \Lampcms\User::factory($this->Registry)->by_id($uid)->setProfitPoint(0 - \Lampcms\Points::BEST_ANSWER)->save(); } catch (\MongoException $e) { e('unable to update the profit point amount for old answerer ' . $e->getMessage()); } } } return $this; }
/** * Create record of new user * * @return \Lampcms\User object User object */ protected function createUser() { $sid = false === ($sid = Cookie::getSidCookie()) ? String::makeSid() : $sid; if (false !== ($tzn = Cookie::get('tzn'))) { $timezone = $tzn; } else { $timezone = $this->Registry->Ini->SERVER_TIMEZONE; } $aUser = array(); $aUser[Schema::EMAIL] = $this->email; $aUser[Schema::REPUTATION] = 1; $aUser[Schema::REGISTRATION_TIMESTAMP] = time(); $aUser[Schema::REGISTRATION_TIME] = date('r'); $aUser[Schema::FIRST_VISIT_TIMESTAMP] = false !== ($intFv = Cookie::getSidCookie(true)) ? $intFv : time(); $aUser[Schema::SID] = $sid; $aUser['google_id'] = (string) $this->userInfo['id']; $aUser['google_token'] = $this->token; if (!empty($this->userInfo['given_name'])) { $aUser[Schema::FIRST_NAME] = $this->userInfo['given_name']; } if (!empty($this->userInfo['family_name'])) { $aUser[Schema::LAST_NAME] = $this->userInfo['family_name']; } if (!empty($this->userInfo['locale'])) { $aUser[Schema::LOCALE] = $this->userInfo['locale']; } if (!empty($this->userInfo['link'])) { $aUser[Schema::URL] = $this->userInfo['link']; } if (!empty($this->userInfo['gender'])) { $aUser[Schema::GENDER] = 'male' === $this->userInfo['gender'] ? 'M' : 'F'; } if (!empty($this->userInfo['name'])) { $username = $this->userInfo['name']; } elseif (!empty($this->userInfo['family_name'])) { $username = !empty($this->userInfo['family_name']); if (!empty($this->userInfo['family_name'])) { $username = '******' . $this->userInfo['family_name']; } } $oEA = \Lampcms\ExternalAuth::factory($this->Registry); $username = $oEA->makeUsername($username); $aUser[Schema::USERNAME] = $username; $aUser[Schema::USERNAME_LOWERCASE] = \mb_strtolower($username); $aUser[Schema::ROLE] = Role::EXTERNAL_USER; $aUser[Schema::TIMEZONE] = $timezone; $aUser[Schema::EXTERNAL_AVATAR] = $this->userInfo['picture'] . '?sz=50'; $aUser = \array_merge($this->Registry->Geo->Location->data, $aUser); d('creating new googlge aUser: '******'new user _id: ' . $User['_id']); \Lampcms\PostRegistration::createReferrerRecord($this->Registry, $User); try { $this->createEmailRecord($User['_id']); } catch (\Lampcms\DevException $e) { e('Unable to create email record: ' . $e->getMessage()); } $this->addContacts($User->getUid()); $this->Registry->Dispatcher->post($User, 'onNewUser'); return $User; }
/** * Change user's user_group_id to registered * and set validation_time to now in EMAILS record * * @throws \Lampcms\NoticeException * @throws \Lampcms\Exception * @return object $this */ protected function activateUser() { $aUser = $this->Registry->Mongo->USERS->findOne(array(Schema::PRIMARY => (int) $this->aEmail['i_uid'])); if (empty($aUser)) { throw new \Lampcms\Exception('@@Unable to find user, please create a new account@@'); } $this->oActivatedUser = User::userFactory($this->Registry, $aUser); $role = $this->oActivatedUser->getRoleId(); /** * If User's role is NOT 'unactivated' then * throw an exception */ if (false === \strstr($role, 'unactivated')) { throw new \Lampcms\NoticeException('@@This account has already been activated@@'); } $this->oActivatedUser->activate()->save(); /** * Now IF Viewer is actually the user that was just activated * we must also update the Viewer! * If we don't then the Viewer object is not updated * and the Viewer in session is still unactivated */ if ($this->Registry->Viewer->equals($this->oActivatedUser)) { $this->processLogin($this->oActivatedUser); } $this->Registry->Dispatcher->post($this->oActivatedUser, 'onUserActivated'); $this->aEmail['i_vts'] = time(); $this->Registry->Mongo->EMAILS->save($this->aEmail); return $this; }
public function testFactory() { $o = \Lampcms\User::factory(new Registry()); $o->setSaved(); $this->assertTrue($o instanceof \Lampcms\User); }
/** * Sets value of lp_u : a link to Last Poster profile * and lp_t a time of last post * * @todo should make the last answerer an array * and then just push the value there * This way if answer is deleted we can just delete * that one element from array! * * @param User $User object of type User who made the last * Answer or Comment to this question * * @param \Lampcms\Answer $Answer * * @return object $this */ public function setLatestAnswer(User $User, Answer $Answer) { $aLatest = $this->offsetGet('a_latest'); $a = array('u' => '<a href="' . $User->getProfileUrl() . '">' . $User->getDisplayName() . '</a>', 't' => date('F j, Y g:i a T', $Answer->getLastModified()), 'id' => $Answer->getResourceId()); /** * Latest answer data goes * to top of array */ \array_unshift($aLatest, $a); $this->offsetSet('a_latest', $aLatest); return $this; }
/** * Attempt to find existing user by email address * Search in EMAILS collection first, then if not found, in USERS collection * If record is found creates User object and returns it * * @return mixed null | User object */ protected function findUserByEmail() { $User = null; /** * Search EMAILS collection * try to find user that has this email address */ $res = $this->Registry->Mongo->EMAILS->findOne(array(Schema::EMAIL => $this->email), array('i_uid' => true)); if (!empty($res) && !empty($res['i_uid'])) { d('found user id by email address. uid: ' . $res['i_uid']); $aUser = $this->Registry->Mongo->USERS->findOne(array(Schema::PRIMARY => $res['i_uid'])); $User = \Lampcms\User::userFactory($this->Registry, $aUser); } /** * Was Not able to find user by search EMAILS collection * Search USERS collection by email address */ if (null === $User) { $a = $this->Registry->Mongo->USERS->findOne(array(Schema::EMAIL => $this->email)); if (!empty($a)) { d('found user id by email address. uid: ' . $a['_id']); $User = \Lampcms\User::userFactory($this->Registry, $a); } } d('User not found by email: ' . $this->email); return $User; }
/** * Create $this->User object * that represents User whose profile * is being viewed currently * * @throws \Lampcms\Exception if user could not be * found by user id passed in request * * @return object $this */ protected function getUser() { $a = $this->Registry->Mongo->USERS->findOne(array('_id' => $this->Request['uid'])); if (empty($a)) { /** * @todo translate string */ throw new \Lampcms\Lampcms404Exception($this->_('User not found')); } $this->User = User::factory($this->Registry, $a); $this->aPageVars['title'] = $this->User->getDisplayName(); return $this; }
/** * Create $this->User User object for user whose * profile is being edited * * @return object $this */ protected function getUser() { $uid = !\Lampcms\Request::isPost() ? $this->Router->getSegment(1, 'i', 0) : $this->Request->get('uid', 'i', null); if ($uid && $uid !== $this->Registry->Viewer->getUid()) { /** * This is edit profile for another user * check Viewer permission here */ $this->checkAccessPermission('edit_any_profile'); $this->User = \Lampcms\User::userFactory($this->Registry)->by_id($uid); } else { $this->User = $this->Registry->Viewer; } return $this; }
/** * Process unfollow user request * * @param User $User who is following * @param int $userid id user user being unfollowed * @throws \InvalidArgumentException * * @return object $this */ public function unfollowUser(User $User, $userid) { if (!is_int($userid)) { throw new \InvalidArgumentException('$userid must be an integer'); } $aFollowed = $User['a_f_u']; d('$aFollowed: ' . \json_encode($aFollowed)); if (false !== ($key = \array_search($userid, $aFollowed))) { d('cp unsetting key: ' . $key); array_splice($aFollowed, $key, 1); $User['a_f_u'] = $aFollowed; $User->save(); $this->Registry->Mongo->USERS->update(array('_id' => $userid), array('$inc' => array('i_flwrs' => -1))); $this->Registry->Dispatcher->post($User, 'onUserUnfollow', array('uid' => $userid)); } else { d('tag ' . $userid . ' is not among the followed users of this userID: ' . $User->getUid()); } return $this; }
/** * * Create new record in USERS collection, * * @return object $this */ protected function createNewUser() { $coll = $this->Registry->Mongo->USERS; $coll->ensureIndex(array(Schema::USERNAME_LOWERCASE => 1), array('unique' => true)); /** * Cannot make email unique index because external users * don't have email, and then value counts as null * and multiple null values count as duplicate! * */ $coll->ensureIndex(array(Schema::EMAIL => 1)); $coll->ensureIndex(array(Schema::ROLE => 1)); /** * Indexes for managing 3 types * of following */ $coll->ensureIndex(array('a_f_t' => 1)); $coll->ensureIndex(array('a_f_u' => 1)); $coll->ensureIndex(array('a_f_q' => 1)); $sid = Cookie::getSidCookie(); if (false !== ($tzn = Cookie::get('tzn'))) { $timezone = $tzn; } else { $timezone = $this->Registry->Ini->SERVER_TIMEZONE; } $aData[Schema::USERNAME] = $this->username; $aData[Schema::USERNAME_LOWERCASE] = \mb_strtolower($this->username); $aData[Schema::EMAIL] = $this->email; $aData[Schema::SID] = false !== $sid ? $sid : \Lampcms\String::makeSid(); $aData[Schema::ROLE] = $this->getRole(); $aData[Schema::TIMEZONE] = $timezone; $aData[Schema::PASSWORD] = String::hashPassword($this->pwd); $aData[Schema::REGISTRATION_TIMESTAMP] = time(); $aData[Schema::REGISTRATION_TIME] = date('r'); $aData[Schema::FIRST_VISIT_TIMESTAMP] = false !== ($intFv = \Lampcms\Cookie::getSidCookie(true)) ? $intFv : time(); $aData[Schema::LOCALE] = $this->Registry->Locale->getLocale(); /** * Initial reputation is always 1 * * @var int */ $aData[Schema::REPUTATION] = 1; $aUser = \array_merge($this->Registry->Geo->Location->data, $aData); d('aUser: '******'new user _id: ' . $User['_id']); $this->processLogin($User); \Lampcms\PostRegistration::createReferrerRecord($this->Registry, $User); return $this; }
/** * * Create new record in USERS collection, * * @return object $this */ protected function createNewUser() { $coll = $this->Registry->Mongo->USERS; $coll->ensureIndex(array('username_lc' => 1), array('unique' => true)); /** * Cannot make email unique index because external users * don't have email, and then value counts as null * and multiple null values count as duplicate! * */ $coll->ensureIndex(array('email' => 1)); $coll->ensureIndex(array('role' => 1)); /** * Indexes for managing 3 types * of following */ $coll->ensureIndex(array('a_f_t' => 1)); $coll->ensureIndex(array('a_f_u' => 1)); $coll->ensureIndex(array('a_f_q' => 1)); $sid = \Lampcms\Cookie::getSidCookie(); $aData['username'] = $this->username; $aData['username_lc'] = strtolower($this->username); $aData['email'] = $this->email; $aData['rs'] = false !== $sid ? $sid : \Lampcms\String::makeSid(); $aData['role'] = $this->getRole(); $aData['tz'] = \Lampcms\TimeZone::getTZbyoffset($this->Request->get('tzo')); $aData['pwd'] = String::hashPassword($this->pwd); $aData['i_reg_ts'] = time(); $aData['date_reg'] = date('r'); $aData['i_fv'] = false !== ($intFv = \Lampcms\Cookie::getSidCookie(true)) ? $intFv : time(); $aData['lang'] = $this->Registry->getCurrentLang(); $aData['locale'] = $this->Registry->Locale->getLocale(); /** * Initial amount of profit point is always 1 * @var int */ $aData['i_pp'] = 0; $aUser = array_merge($this->Registry->Geo->Location->data, $aData); d('aUser: '******'id: ' . $User['_id']); $this->processLogin($User); \Lampcms\PostRegistration::createReferrerRecord($this->Registry, $User); return $this; }
/** * Check if this user has same userID * as user object passed to this method * * @param \Lampcms\User $User * * @internal param \Lampcms\User $user another User object * * @return bool true if User object passed here has the same user id */ public function equals(User $User) { return $User->getUid() === $this->getUid(); }
/** * Approve pending resource * * @param User $Moderator User object of user who approved this Question * * @return mixed true if status was changed|int status code of question */ public function setApprovedStatus(\Lampcms\User $Moderator) { $status = $this->offsetGet(Schema::RESOURCE_STATUS_ID); if ($status === Schema::PENDING) { $this->offsetSet(Schema::RESOURCE_STATUS_ID, Schema::POSTED); $this->offsetSet(Schema::APPROVED_BY_ID, $Moderator->getUid()); $this->offsetSet(Schema::APPROVED_BY_USERNAME, $Moderator->getDisplayName()); $this->offsetSet(Schema::APPROVED_TIMESTAMP, time()); $this->touch(true); $this->save(); return true; } return $status; }
/** * Decrease reputation of user who * owns the old answer * * @todo check current score and make sure * it will not become negative after we deduct * some points * * @return object $this */ protected function updateOldAnswerer() { if (!empty($this->aOldAnswer)) { $uid = $this->aOldAnswer[Schema::POSTER_ID]; if (!empty($uid)) { try { \Lampcms\User::userFactory($this->Registry)->by_id($uid)->setReputation(0 - $this->Registry->Ini->POINTS->BEST_ANSWER)->save(); } catch (\MongoException $e) { e('unable to update reputation for old answerer ' . $e->getMessage()); } } } return $this; }
/** * Change user's user_group_id to registered * and set validation_time to now in EMAILS record * * @return object $this */ protected function activateUser() { $aUser = $this->Registry->Mongo->USERS->findOne(array('_id' => (int) $this->aEmail['i_uid'])); if (empty($aUser)) { /** * @todo translate string */ throw new \Lampcms\Exception($this->_('Unable to find user, please create a new account')); } $this->oActivatedUser = User::factory($this->Registry, $aUser); $role = $this->oActivatedUser->getRoleId(); /** * If User's role is NOT 'unactivated' then * throw an exception */ if (false === \strstr($role, 'unactivated')) { e('Account already activated. ' . $role . ' $aUser: '******'This account has already been activated')); } $this->oActivatedUser->activate()->save(); /** * Now IF Viewer is actually the user that was just activated * we must also update the Viewer! * If we don't then the Viewer object is not updated * and the Viewer in session is still unactivated */ if ($this->Registry->Viewer->equals($this->oActivatedUser)) { $this->processLogin($this->oActivatedUser); } $this->Registry->Dispatcher->post($this->oActivatedUser, 'onUserActivated'); $this->aEmail['i_vts'] = time(); $this->Registry->Mongo->EMAILS->save($this->aEmail); return $this; }
/** * * Change role of Question or Answer poster * to 'Banned' * * @return $this; * */ protected function banUser() { $ban = $this->Request->get('ban', 's', ''); d('ban: ' . $ban); if (!empty($ban) && $this->checkAccessPermission('ban_user')) { $User = User::userFactory($this->Registry)->by_id($this->Resource->getOwnerId()); $User->setRoleId('suspended'); $User->save(); $this->Registry->Dispatcher->post($User, 'onUserBanned'); } return $this; }