2013-10-12 14:53:47 +02:00
|
|
|
<?php
|
2013-10-28 11:19:15 +01:00
|
|
|
class Model_User extends AbstractModel
|
2013-10-12 14:53:47 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
const SETTING_SAFETY = 1;
|
|
|
|
const SETTING_ENDLESS_SCROLLING = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static function getTableName()
|
|
|
|
{
|
|
|
|
return 'user';
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getQueryBuilder()
|
|
|
|
{
|
|
|
|
return 'Model_User_QueryBuilder';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-10-21 14:32:47 +02:00
|
|
|
public static function locate($key, $throw = true)
|
2013-10-17 22:57:32 +02:00
|
|
|
{
|
2013-11-21 22:29:38 +01:00
|
|
|
$user = R::findOne(self::getTableName(), 'LOWER(name) = LOWER(?)', [$key]);
|
2013-11-16 18:51:34 +01:00
|
|
|
if ($user)
|
|
|
|
return $user;
|
|
|
|
|
|
|
|
$user = R::findOne(self::getTableName(), 'LOWER(email_confirmed) = LOWER(?)', [trim($key)]);
|
|
|
|
if ($user)
|
|
|
|
return $user;
|
|
|
|
|
|
|
|
if ($throw)
|
|
|
|
throw new SimpleException('Invalid user name "' . $key . '"');
|
|
|
|
|
|
|
|
return null;
|
2013-10-17 22:57:32 +02:00
|
|
|
}
|
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
public static function create()
|
2013-10-12 14:53:47 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
$user = R::dispense(self::getTableName());
|
|
|
|
$user->pass_salt = md5(mt_rand() . uniqid());
|
|
|
|
return $user;
|
2013-10-12 14:53:47 +02:00
|
|
|
}
|
2013-10-14 00:25:40 +02:00
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
public static function remove($user)
|
2013-10-14 00:25:40 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
//remove stuff from auxiliary tables
|
|
|
|
R::trashAll(R::find('postscore', 'user_id = ?', [$user->id]));
|
|
|
|
foreach ($user->alias('commenter')->ownComment as $comment)
|
2013-10-14 00:25:40 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
$comment->commenter = null;
|
|
|
|
R::store($comment);
|
2013-10-14 00:25:40 +02:00
|
|
|
}
|
2013-11-22 21:20:56 +01:00
|
|
|
foreach ($user->alias('uploader')->ownPost as $post)
|
2013-10-14 00:25:40 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
$post->uploader = null;
|
|
|
|
R::store($post);
|
2013-10-14 00:25:40 +02:00
|
|
|
}
|
2013-11-22 21:20:56 +01:00
|
|
|
$user->ownFavoritee = [];
|
|
|
|
R::store($user);
|
|
|
|
R::trash($user);
|
2013-10-14 00:25:40 +02:00
|
|
|
}
|
2013-10-15 13:14:48 +02:00
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
public static function save($user)
|
2013-10-22 00:17:06 +02:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
R::store($user);
|
2013-10-22 00:17:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
public static function getAnonymousName()
|
|
|
|
{
|
|
|
|
return '[Anonymous user]';
|
|
|
|
}
|
2013-10-22 00:17:06 +02:00
|
|
|
|
2013-10-15 13:14:48 +02:00
|
|
|
public static function validateUserName($userName)
|
|
|
|
{
|
|
|
|
$userName = trim($userName);
|
|
|
|
|
2013-11-21 22:29:38 +01:00
|
|
|
$dbUser = R::findOne(self::getTableName(), 'LOWER(name) = LOWER(?)', [$userName]);
|
2013-10-15 13:14:48 +02:00
|
|
|
if ($dbUser !== null)
|
|
|
|
{
|
2013-10-16 18:07:23 +02:00
|
|
|
if (!$dbUser->email_confirmed and \Chibi\Registry::getConfig()->registration->needEmailForRegistering)
|
2013-10-15 13:14:48 +02:00
|
|
|
throw new SimpleException('User with this name is already registered and awaits e-mail confirmation');
|
|
|
|
|
|
|
|
if (!$dbUser->staff_confirmed and \Chibi\Registry::getConfig()->registration->staffActivation)
|
2013-10-15 20:22:52 +02:00
|
|
|
throw new SimpleException('User with this name is already registered and awaits staff confirmation');
|
2013-10-15 13:14:48 +02:00
|
|
|
|
|
|
|
throw new SimpleException('User with this name is already registered');
|
|
|
|
}
|
|
|
|
|
|
|
|
$userNameMinLength = intval(\Chibi\Registry::getConfig()->registration->userNameMinLength);
|
2013-10-19 20:51:32 +02:00
|
|
|
$userNameMaxLength = intval(\Chibi\Registry::getConfig()->registration->userNameMaxLength);
|
2013-10-15 13:14:48 +02:00
|
|
|
$userNameRegex = \Chibi\Registry::getConfig()->registration->userNameRegex;
|
|
|
|
|
|
|
|
if (strlen($userName) < $userNameMinLength)
|
|
|
|
throw new SimpleException(sprintf('User name must have at least %d characters', $userNameMinLength));
|
|
|
|
|
2013-10-19 20:51:32 +02:00
|
|
|
if (strlen($userName) > $userNameMaxLength)
|
|
|
|
throw new SimpleException(sprintf('User name must have at most %d characters', $userNameMaxLength));
|
|
|
|
|
2013-10-15 13:14:48 +02:00
|
|
|
if (!preg_match($userNameRegex, $userName))
|
|
|
|
throw new SimpleException('User name contains invalid characters');
|
|
|
|
|
|
|
|
return $userName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function validatePassword($password)
|
|
|
|
{
|
|
|
|
$passMinLength = intval(\Chibi\Registry::getConfig()->registration->passMinLength);
|
|
|
|
$passRegex = \Chibi\Registry::getConfig()->registration->passRegex;
|
|
|
|
|
|
|
|
if (strlen($password) < $passMinLength)
|
|
|
|
throw new SimpleException(sprintf('Password must have at least %d characters', $passMinLength));
|
|
|
|
|
|
|
|
if (!preg_match($passRegex, $password))
|
|
|
|
throw new SimpleException('Password contains invalid characters');
|
|
|
|
|
|
|
|
return $password;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function validateEmail($email)
|
|
|
|
{
|
|
|
|
$email = trim($email);
|
|
|
|
|
|
|
|
if (!empty($email) and !TextHelper::isValidEmail($email))
|
|
|
|
throw new SimpleException('E-mail address appears to be invalid');
|
|
|
|
|
|
|
|
return $email;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function validateAccessRank($accessRank)
|
|
|
|
{
|
|
|
|
$accessRank = intval($accessRank);
|
|
|
|
|
|
|
|
if (!in_array($accessRank, AccessRank::getAll()))
|
|
|
|
throw new SimpleException('Invalid access rank type "' . $accessRank . '"');
|
|
|
|
|
2013-10-16 13:12:17 +02:00
|
|
|
if ($accessRank == AccessRank::Nobody)
|
|
|
|
throw new SimpleException('Cannot set special accesss rank "' . $accessRank . '"');
|
|
|
|
|
2013-10-15 13:14:48 +02:00
|
|
|
return $accessRank;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function hashPassword($pass, $salt2)
|
|
|
|
{
|
2013-10-22 11:40:10 +02:00
|
|
|
$salt1 = \Chibi\Registry::getConfig()->main->salt;
|
2013-10-15 13:14:48 +02:00
|
|
|
return sha1($salt1 . $salt2 . $pass);
|
|
|
|
}
|
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
public function getAvatarUrl($size = 32)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
$subject = !empty($this->email_confirmed)
|
|
|
|
? $this->email_confirmed
|
|
|
|
: $this->pass_salt . $this->name;
|
|
|
|
$hash = md5(strtolower(trim($subject)));
|
|
|
|
$url = 'http://www.gravatar.com/avatar/' . $hash . '?s=' . $size . '&d=retro';
|
|
|
|
return $url;
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
|
|
|
|
2013-11-22 21:20:56 +01:00
|
|
|
public function getSetting($key)
|
2013-10-28 11:19:15 +01:00
|
|
|
{
|
2013-11-22 21:20:56 +01:00
|
|
|
$settings = json_decode($this->settings, true);
|
|
|
|
return isset($settings[$key])
|
|
|
|
? $settings[$key]
|
|
|
|
: null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setSetting($key, $value)
|
|
|
|
{
|
|
|
|
$settings = json_decode($this->settings, true);
|
|
|
|
$settings[$key] = $value;
|
|
|
|
$settings = json_encode($settings);
|
|
|
|
if (strlen($settings) > 200)
|
|
|
|
throw new SimpleException('Too much data');
|
|
|
|
$this->settings = $settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasEnabledSafety($safety)
|
|
|
|
{
|
|
|
|
$all = $this->getSetting(self::SETTING_SAFETY);
|
|
|
|
if (!$all)
|
|
|
|
return $safety == PostSafety::Safe;
|
|
|
|
return $all & PostSafety::toFlag($safety);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function enableSafety($safety, $enabled)
|
|
|
|
{
|
|
|
|
$all = $this->getSetting(self::SETTING_SAFETY);
|
|
|
|
if (!$all)
|
|
|
|
$all = PostSafety::toFlag(PostSafety::Safe);
|
|
|
|
|
|
|
|
$new = $all;
|
|
|
|
if (!$enabled)
|
|
|
|
{
|
|
|
|
$new &= ~PostSafety::toFlag($safety);
|
|
|
|
if (!$new)
|
|
|
|
$new = PostSafety::toFlag(PostSafety::Safe);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$new |= PostSafety::toFlag($safety);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->setSetting(self::SETTING_SAFETY, $new);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasEnabledEndlessScrolling()
|
|
|
|
{
|
|
|
|
$ret = $this->getSetting(self::SETTING_ENDLESS_SCROLLING);
|
|
|
|
if ($ret === null)
|
|
|
|
$ret = \Chibi\Registry::getConfig()->browsing->endlessScrollingDefault;
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function enableEndlessScrolling($enabled)
|
|
|
|
{
|
|
|
|
$this->setSetting(self::SETTING_ENDLESS_SCROLLING, $enabled ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasFavorited($post)
|
|
|
|
{
|
|
|
|
foreach ($this->bean->ownFavoritee as $fav)
|
|
|
|
if ($fav->post->id == $post->id)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getScore($post)
|
|
|
|
{
|
|
|
|
$s = R::findOne('postscore', 'post_id = ? AND user_id = ?', [$post->id, $this->id]);
|
|
|
|
if ($s)
|
|
|
|
return intval($s->score);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function addToFavorites($post)
|
|
|
|
{
|
|
|
|
R::preload($this->bean, ['favoritee' => 'post']);
|
|
|
|
foreach ($this->bean->ownFavoritee as $fav)
|
|
|
|
if ($fav->post_id == $post->id)
|
|
|
|
throw new SimpleException('Already in favorites');
|
|
|
|
|
|
|
|
$this->bean->link('favoritee')->post = $post;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function remFromFavorites($post)
|
|
|
|
{
|
|
|
|
$finalKey = null;
|
|
|
|
foreach ($this->bean->ownFavoritee as $key => $fav)
|
|
|
|
if ($fav->post_id == $post->id)
|
|
|
|
$finalKey = $key;
|
|
|
|
|
|
|
|
if ($finalKey === null)
|
|
|
|
throw new SimpleException('Not in favorites');
|
|
|
|
|
|
|
|
unset($this->bean->ownFavoritee[$finalKey]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function score($post, $score)
|
|
|
|
{
|
|
|
|
R::trashAll(R::find('postscore', 'post_id = ? AND user_id = ?', [$post->id, $this->id]));
|
|
|
|
$score = intval($score);
|
|
|
|
if ($score != 0)
|
|
|
|
{
|
|
|
|
$p = $this->bean->link('postscore');
|
|
|
|
$p->post = $post;
|
|
|
|
$p->score = $score;
|
|
|
|
}
|
2013-10-28 11:19:15 +01:00
|
|
|
}
|
2013-10-12 14:53:47 +02:00
|
|
|
}
|