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.

229 lines
7.2 KiB

8 years ago
8 years ago
8 years ago
  1. <?php
  2. namespace App;
  3. use Movim\Image;
  4. use Movim\ImageSize;
  5. use Movim\Session;
  6. use Moxl\Xec\Action\Presence\Muc;
  7. use Awobaz\Compoships\Database\Eloquent\Model;
  8. class Presence extends Model
  9. {
  10. protected $primaryKey = ['session_id', 'jid', 'resource'];
  11. public $incrementing = false;
  12. protected $attributes = [
  13. 'session_id' => SESSION_ID,
  14. 'muc' => false
  15. ];
  16. protected $fillable = [
  17. 'session_id',
  18. 'jid',
  19. 'resource',
  20. 'mucjid'
  21. ];
  22. public function roster()
  23. {
  24. return $this->hasOne('App\Roster', 'jid', 'jid')
  25. ->where('session_id', $this->session_id);
  26. }
  27. public function capability()
  28. {
  29. return $this->hasOne('App\Info', 'node', 'node')
  30. ->whereNull('server');
  31. }
  32. public function contact()
  33. {
  34. return $this->hasOne('App\Contact', 'id', 'jid');
  35. }
  36. public function getSeenAttribute(): ?string
  37. {
  38. if ($this->value == 1) return null;
  39. // XEP-0319
  40. if ($this->idle) {
  41. return $this->idle;
  42. }
  43. // ...supersedes XEP-0256
  44. elseif ($this->resource == '' && $this->delay) {
  45. $delay = strtotime($this->delay);
  46. if ($this->last) $delay += $this->last;
  47. return gmdate('Y-m-d H:i:s', $delay);
  48. } elseif ($this->delay) {
  49. return $this->delay;
  50. }
  51. return null;
  52. }
  53. /**
  54. * Fallback case if we don't have a contact
  55. */
  56. public function getPicture(ImageSize $size = ImageSize::M): string
  57. {
  58. return getPicture($this->jid, $this->jid, $size);
  59. }
  60. public function getPresencetextAttribute()
  61. {
  62. return getPresences()[$this->value];
  63. }
  64. public function getPresencekeyAttribute()
  65. {
  66. return getPresencesTxt()[$this->value];
  67. }
  68. public function getConferencePictureAttribute(): string
  69. {
  70. return Image::getOrCreate($this->mucjid, 120) ?? avatarPlaceholder($this->resource . 'groupchat');
  71. }
  72. public function getConferenceColorAttribute()
  73. {
  74. return stringToColor(
  75. $this->resource . 'groupchat'
  76. );
  77. }
  78. public static function findByStanza($stanza)
  79. {
  80. $temporary = new self;
  81. $temporary->set($stanza);
  82. return $temporary;
  83. }
  84. public function set($stanza)
  85. {
  86. $this->session_id = SESSION_ID;
  87. $jid = explodeJid($stanza->attributes()->from);
  88. $this->jid = $jid['jid'];
  89. $this->resource = $jid['resource'] ?? '';
  90. $this->type = $stanza->attributes()->type ?? null;
  91. if ($stanza->status && !empty((string)$stanza->status)) {
  92. $this->status = (string)$stanza->status;
  93. }
  94. if ($stanza->c) {
  95. $this->node = (string)$stanza->c->attributes()->node .
  96. '#' . (string)$stanza->c->attributes()->ver;
  97. }
  98. $this->priority = ($stanza->priority) ? (int)$stanza->priority : 0;
  99. if ((string)$stanza->attributes()->type == 'error') {
  100. $this->value = 6;
  101. } elseif (
  102. (string)$stanza->attributes()->type == 'unavailable'
  103. || (string)$stanza->attributes()->type == 'unsubscribed'
  104. ) {
  105. $this->value = 5;
  106. } elseif ((string)$stanza->show == 'away') {
  107. $this->value = 2;
  108. } elseif ((string)$stanza->show == 'dnd') {
  109. $this->value = 3;
  110. } elseif ((string)$stanza->show == 'xa') {
  111. $this->value = 4;
  112. } else {
  113. $this->value = 1;
  114. }
  115. // Specific XEP
  116. if ($stanza->x) {
  117. foreach ($stanza->children() as $name => $c) {
  118. switch ($c->attributes()->xmlns) {
  119. case 'http://jabber.org/protocol/muc':
  120. case 'http://jabber.org/protocol/muc#user':
  121. $this->muc = true;
  122. $session = Session::instance();
  123. if ($session->get(Muc::$mucId . (string)$stanza->attributes()->from)) {
  124. $this->mucjid = \App\User::me()->id;
  125. }
  126. if (!isset($c->item)) {
  127. break;
  128. }
  129. if (!empty($c->xpath("//status[@code='110']"))) {
  130. $this->mucjid = \App\User::me()->id;
  131. } elseif ($c->item->attributes()->jid) {
  132. $this->mucjid = cleanJid((string)$c->item->attributes()->jid);
  133. } else {
  134. $this->mucjid = (string)$stanza->attributes()->from;
  135. }
  136. if ($c->item->attributes()->role) {
  137. $this->mucrole = (string)$c->item->attributes()->role;
  138. }
  139. if ($c->item->attributes()->affiliation) {
  140. $this->mucaffiliation = (string)$c->item->attributes()->affiliation;
  141. }
  142. break;
  143. case 'vcard-temp:x:update':
  144. if (!empty((string)$c->photo)) {
  145. $this->avatarhash = (string)$c->photo;
  146. }
  147. break;
  148. }
  149. }
  150. }
  151. if ($stanza->delay && $stanza->delay->attributes()->xmlns == 'urn:xmpp:delay') {
  152. $this->delay = gmdate(
  153. 'Y-m-d H:i:s',
  154. strtotime(
  155. (string)$stanza->delay->attributes()->stamp
  156. )
  157. );
  158. }
  159. if ($stanza->idle && $stanza->idle->attributes()->xmlns == 'urn:xmpp:idle:1') {
  160. $this->idle = gmdate(
  161. 'Y-m-d H:i:s',
  162. strtotime(
  163. (string)$stanza->idle->attributes()->since
  164. )
  165. );
  166. }
  167. if ($stanza->query && $stanza->query->attributes()->xmlns == 'jabber:iq:last') {
  168. $this->last = (int)$stanza->query->attributes()->seconds;
  169. }
  170. }
  171. public function toArray()
  172. {
  173. $now = \Carbon\Carbon::now();
  174. return [
  175. 'session_id' => $this->attributes['session_id'] ?? null,
  176. 'jid' => $this->attributes['jid'] ?? null,
  177. 'resource' => $this->attributes['resource'] ?? null,
  178. 'value' => $this->attributes['value'] ?? null,
  179. 'type' => $this->attributes['type'] ?? null,
  180. 'priority' => $this->attributes['priority'] ?? null,
  181. 'status' => $this->attributes['status'] ?? null,
  182. 'node' => $this->attributes['node'] ?? null,
  183. 'delay' => $this->attributes['delay'] ?? null,
  184. 'last' => $this->attributes['last'] ?? null,
  185. 'idle' => $this->attributes['idle'] ?? null,
  186. 'muc' => $this->attributes['muc'] ?? null,
  187. 'mucjid' => $this->attributes['mucjid'] ?? null,
  188. 'mucaffiliation' => $this->attributes['mucaffiliation'] ?? null,
  189. 'mucrole' => $this->attributes['mucrole'] ?? null,
  190. 'created_at' => $this->attributes['created_at'] ?? $now,
  191. 'updated_at' => $this->attributes['updated_at'] ?? $now,
  192. 'avatarhash' => $this->attributes['avatarhash'] ?? null,
  193. ];
  194. }
  195. }