You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
7.6 KiB

8 years ago
  1. <?php
  2. namespace App;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Movim\Session;
  5. use App\Contact;
  6. use App\Configuration;
  7. use Illuminate\Database\Capsule\Manager as DB;
  8. class User extends Model
  9. {
  10. protected $fillable = [
  11. 'id', 'language', 'nightmode', 'chatmain', 'nsfw', 'nickname',
  12. 'notificationchat', 'notificationcall', 'omemoenabled'
  13. ];
  14. public $with = ['session', 'capability'];
  15. protected $keyType = 'string';
  16. public $incrementing = false;
  17. private static $me = null;
  18. private $unreads = null;
  19. private $blockListInitialized = false;
  20. private $userBlocked = [];
  21. private $globalBlocked = [];
  22. protected $casts = [
  23. 'posts_since' => 'datetime:Y-m-d H:i:s',
  24. 'notifications_since' => 'datetime:Y-m-d H:i:s',
  25. ];
  26. public function save(array $options = [])
  27. {
  28. parent::save($options);
  29. // Reload the user
  30. self::me(true);
  31. (new \Movim\Bootstrap)->loadLanguage();
  32. }
  33. public function session()
  34. {
  35. return $this->hasOne('App\Session');
  36. }
  37. public function contact()
  38. {
  39. return $this->hasOne('App\Contact', 'id');
  40. }
  41. public function capability()
  42. {
  43. return $this->hasOne('App\Info', 'server', 'id')->where('node', '');
  44. }
  45. public function messages()
  46. {
  47. return $this->hasMany('App\Message');
  48. }
  49. public function openChats()
  50. {
  51. return $this->hasMany('App\OpenChat');
  52. }
  53. public function drafts()
  54. {
  55. return $this->hasMany('App\Draft');
  56. }
  57. public function bundles()
  58. {
  59. return $this->hasMany('App\Bundle');
  60. }
  61. public function pushSubscriptions()
  62. {
  63. return $this->hasMany('App\PushSubscription');
  64. }
  65. public function reported()
  66. {
  67. return $this->belongsToMany('App\Reported')->withTimestamps();
  68. }
  69. public function postViews()
  70. {
  71. return $this->belongsToMany(User::class, 'post_user_views', 'user_id', 'post_id')->withTimestamps();
  72. }
  73. public function emojis()
  74. {
  75. return $this->belongsToMany('App\Emoji')->withPivot('alias')->withTimestamps();
  76. }
  77. public function getUsernameAttribute()
  78. {
  79. return $this->contact && $this->contact->nickname
  80. ? $this->contact->nickname
  81. : $this->session->username;
  82. }
  83. public function getResolvedNicknameAttribute()
  84. {
  85. return $this->nickname ?? $this->id;
  86. }
  87. public function unreads(string $jid = null, bool $quoted = false, bool $cached = false): int
  88. {
  89. if ($this->unreads !== null && $cached) return $this->unreads;
  90. $union = DB::table('messages')
  91. ->where('user_id', $this->id)
  92. ->where('seen', false)
  93. ->whereIn('type', ['chat', 'headline', 'invitation']);
  94. $union = ($jid)
  95. ? $union->where('jidfrom', $jid)
  96. : $union->where('jidfrom', '!=', $this->id);
  97. $unreads = $this->messages()
  98. ->where('seen', false)
  99. ->where('jidfrom', '!=', $this->id)
  100. ->where(function ($query) use ($quoted) {
  101. $query->where('type', 'groupchat')
  102. ->whereNull('subject')
  103. ->whereIn('jidfrom', function ($query) {
  104. $query->select('conference')
  105. ->from('conferences')
  106. ->where('session_id', function ($query) {
  107. $query->select('id')
  108. ->from('sessions')
  109. ->where('user_id', $this->id);
  110. });
  111. });
  112. if ($quoted) {
  113. $query->where('quoted', true);
  114. }
  115. })->unionAll($union);
  116. if ($jid) {
  117. $unreads = $unreads->where('jidfrom', $jid);
  118. } else {
  119. $unreads = $unreads->distinct('jidfrom');
  120. }
  121. $unreads = $unreads->count();
  122. if ($jid == null) {
  123. $this->unreads = $unreads;
  124. }
  125. return $unreads;
  126. }
  127. public function encryptedPasswords()
  128. {
  129. return $this->hasMany('App\EncryptedPassword');
  130. }
  131. public function subscriptions()
  132. {
  133. return $this->hasMany('App\Subscription', 'jid', 'id');
  134. }
  135. public function affiliations()
  136. {
  137. return $this->hasMany('App\Affiliation', 'jid', 'id');
  138. }
  139. public static function me($reload = false): User
  140. {
  141. $session = Session::start();
  142. if (
  143. self::$me != null
  144. && self::$me->id == $session->get('jid')
  145. && $reload == false
  146. ) {
  147. return self::$me;
  148. }
  149. $me = self::find($session->get('jid'));
  150. self::$me = $me;
  151. return ($me) ? $me : new User;
  152. }
  153. public function init()
  154. {
  155. $contact = Contact::firstOrNew(['id' => $this->id]);
  156. $contact->save();
  157. }
  158. public function setConfig(array $config)
  159. {
  160. if (isset($config['language'])) {
  161. $this->language = (string)$config['language'];
  162. }
  163. if (isset($config['nsfw'])) {
  164. $this->nsfw = (bool)$config['nsfw'];
  165. }
  166. if (isset($config['omemoenabled'])) {
  167. $this->omemoenabled = (bool)$config['omemoenabled'];
  168. }
  169. if (isset($config['chatmain'])) {
  170. $this->chatmain = (bool)$config['chatmain'];
  171. }
  172. if (isset($config['nightmode'])) {
  173. $this->nightmode = (bool)$config['nightmode'];
  174. }
  175. if (isset($config['notificationcall'])) {
  176. $this->notificationcall = (bool)$config['notificationcall'];
  177. }
  178. if (isset($config['notificationchat'])) {
  179. $this->notificationchat = (bool)$config['notificationchat'];
  180. }
  181. }
  182. public function hasMAM(): bool
  183. {
  184. return ($this->capability && $this->capability->hasFeature('urn:xmpp:mam:2'));
  185. }
  186. public function hasBookmarksConvertion(): bool
  187. {
  188. return ($this->capability && $this->capability->hasFeature('urn:xmpp:bookmarks:1#compat'));
  189. }
  190. public function hasOMEMO(): bool
  191. {
  192. return (bool)$this->omemoenabled;
  193. }
  194. public function hasPubsub()
  195. {
  196. $configuration = Configuration::get();
  197. return (!$configuration->chatonly
  198. && $this->capability
  199. && $this->capability->hasFeature('http://jabber.org/protocol/pubsub#persistent-items')
  200. && ($this->capability->hasFeature('http://jabber.org/protocol/pubsub#multi-items')
  201. || ($this->session->serverCapability
  202. && $this->session->serverCapability->hasFeature('http://jabber.org/protocol/pubsub#multi-items')
  203. )
  204. )
  205. );
  206. }
  207. public function hasUpload(): bool
  208. {
  209. return ($this->session && $this->session->getUploadService());
  210. }
  211. public function setPublic()
  212. {
  213. $this->attributes['public'] = true;
  214. $this->save();
  215. }
  216. public function setPrivate()
  217. {
  218. $this->attributes['public'] = false;
  219. $this->save();
  220. }
  221. public function refreshBlocked()
  222. {
  223. $this->blockListInitialized = true;
  224. $this->userBlocked = (array)$this->reported()->get()->pluck('id')->toArray();
  225. $this->globalBlocked = (array)Reported::where('blocked', true)->get()->pluck('id')->toArray();
  226. }
  227. public function hasBlocked(string $jid, bool $localOnly = false): bool
  228. {
  229. if ($this->blockListInitialized == false) {
  230. $this->refreshBlocked();
  231. }
  232. if ($localOnly) {
  233. return in_array($jid, $this->userBlocked);
  234. }
  235. return in_array($jid, $this->userBlocked) || in_array($jid, $this->globalBlocked);
  236. }
  237. }