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.

218 lines
6.7 KiB

8 years ago
8 years ago
8 years ago
  1. <?php
  2. namespace App;
  3. use Movim\Model;
  4. use Movim\Picture;
  5. use Movim\Session;
  6. use App\PresenceBuffer;
  7. class Presence extends Model
  8. {
  9. protected $primaryKey = ['session_id', 'jid', 'resource'];
  10. public $incrementing = false;
  11. protected $attributes = [
  12. 'session_id' => SESSION_ID,
  13. 'muc' => false
  14. ];
  15. protected $fillable = [
  16. 'session_id',
  17. 'jid',
  18. 'resource',
  19. 'mucjid'
  20. ];
  21. public function roster()
  22. {
  23. return $this->hasOne('App\Roster', 'jid', 'jid')
  24. ->where('session_id', $this->session_id);
  25. }
  26. public function capability()
  27. {
  28. return $this->hasOne('App\Info', 'node', 'node');
  29. }
  30. public function contact()
  31. {
  32. return $this->hasOne('App\Contact', 'id', 'jid');
  33. }
  34. public function getPresencetextAttribute()
  35. {
  36. return getPresences()[$this->value];
  37. }
  38. public function getPresencekeyAttribute()
  39. {
  40. return getPresencesTxt()[$this->value];
  41. }
  42. public function getConferencePictureAttribute()
  43. {
  44. return (new Picture)->get($this->mucjid, 120);
  45. }
  46. public function getRefreshableAttribute()
  47. {
  48. if (!$this->avatarhash) {
  49. return false;
  50. }
  51. $jid = ($this->muc)
  52. ? ($this->mucjid)
  53. ? $this->mucjid
  54. : $this->jid.'/'.$this->resource
  55. : $this->jid;
  56. $contact = \App\Contact::where('avatarhash', (string)$this->avatarhash)->first();
  57. /*
  58. * Another contact had the same avatar
  59. */
  60. if ($contact
  61. && $contact->id != $jid
  62. && $this->muc) {
  63. $p = new Picture;
  64. $p->fromKey($contact->id);
  65. $p->set($jid);
  66. return false;
  67. }
  68. return ($contact) ? false : $jid;
  69. }
  70. public static function findByStanza($stanza)
  71. {
  72. $buffer = PresenceBuffer::getInstance();
  73. $temporary = new self;
  74. $temporary->set($stanza);
  75. if ($buffer->saved($temporary)) {
  76. $jid = explode('/', (string)$stanza->attributes()->from);
  77. return self::firstOrNew([
  78. 'session_id' => SESSION_ID,
  79. 'jid' => $jid[0],
  80. 'resource' => isset($jid[1]) ? $jid[1] : ''
  81. ]);
  82. }
  83. return $temporary;
  84. }
  85. public function set($stanza)
  86. {
  87. $this->session_id = SESSION_ID;
  88. $jid = explodeJid($stanza->attributes()->from);
  89. $this->jid = $jid['jid'];
  90. $this->resource = $jid['resource'] ?? '';
  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 ((string)$stanza->attributes()->type == 'unavailable'
  102. || (string)$stanza->attributes()->type == 'unsubscribed') {
  103. $this->value = 5;
  104. } elseif ((string)$stanza->show == 'away') {
  105. $this->value = 2;
  106. } elseif ((string)$stanza->show == 'dnd') {
  107. $this->value = 3;
  108. } elseif ((string)$stanza->show == 'xa') {
  109. $this->value = 4;
  110. } else {
  111. $this->value = 1;
  112. }
  113. // Specific XEP
  114. if ($stanza->x) {
  115. foreach ($stanza->children() as $name => $c) {
  116. switch ($c->attributes()->xmlns) {
  117. /*case 'jabber:x:signed' :
  118. $this->publickey = (string)$c;
  119. break;*/
  120. case 'http://jabber.org/protocol/muc#user':
  121. if (!isset($c->item)) {
  122. break;
  123. }
  124. $session = Session::start();
  125. $this->muc = true;
  126. /**
  127. * If we were trying to connect to that particular MUC
  128. * See Moxl\Xec\Action\Presence\Muc
  129. */
  130. if ($session->get((string)$stanza->attributes()->from)) {
  131. $this->mucjid = \App\User::me()->id;
  132. } elseif ($c->item->attributes()->jid) {
  133. $this->mucjid = cleanJid((string)$c->item->attributes()->jid);
  134. } else {
  135. $this->mucjid = (string)$stanza->attributes()->from;
  136. }
  137. if ($c->item->attributes()->role) {
  138. $this->mucrole = (string)$c->item->attributes()->role;
  139. }
  140. if ($c->item->attributes()->affiliation) {
  141. $this->mucaffiliation = (string)$c->item->attributes()->affiliation;
  142. }
  143. break;
  144. case 'vcard-temp:x:update':
  145. $this->avatarhash = (string)$c->photo;
  146. break;
  147. }
  148. }
  149. }
  150. if ($stanza->delay) {
  151. $this->delay = gmdate(
  152. 'Y-m-d H:i:s',
  153. strtotime(
  154. (string)$stanza->delay->attributes()->stamp
  155. )
  156. );
  157. }
  158. if ($stanza->query) {
  159. $this->last = (int)$stanza->query->attributes()->seconds;
  160. }
  161. }
  162. public function toArray()
  163. {
  164. $now = \Carbon\Carbon::now();
  165. return [
  166. 'session_id' => $this->attributes['session_id'] ?? null,
  167. 'jid' => $this->attributes['jid'] ?? null,
  168. 'resource' => $this->attributes['resource'] ?? null,
  169. 'value' => $this->attributes['value'] ?? null,
  170. 'priority' => $this->attributes['priority'] ?? null,
  171. 'status' => $this->attributes['status'] ?? null,
  172. 'node' => $this->attributes['node'] ?? null,
  173. 'delay' => $this->attributes['delay'] ?? null,
  174. 'last' => $this->attributes['last'] ?? null,
  175. 'muc' => $this->attributes['muc'] ?? null,
  176. 'mucjid' => $this->attributes['mucjid'] ?? null,
  177. 'mucaffiliation' => $this->attributes['mucaffiliation'] ?? null,
  178. 'mucrole' => $this->attributes['mucrole'] ?? null,
  179. 'created_at' => $this->attributes['created_at'] ?? $now,
  180. 'updated_at' => $this->attributes['updated_at'] ?? $now,
  181. 'avatarhash' => $this->attributes['avatar_hash'] ?? null,
  182. ];
  183. }
  184. }