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.

418 lines
12 KiB

8 years ago
  1. <?php
  2. namespace App;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Capsule\Manager as DB;
  5. use Respect\Validation\Validator;
  6. use Movim\Image;
  7. class Contact extends Model
  8. {
  9. protected $fillable = ['id', 'nickname', 'mood'];
  10. protected $keyType = 'string';
  11. public $incrementing = false;
  12. public function user()
  13. {
  14. return $this->belongsTo('App\User', 'id');
  15. }
  16. public function scopePublic($query, $like = false)
  17. {
  18. return $query->whereIn('id', function ($query) use ($like) {
  19. $query->select('id')
  20. ->from('users')
  21. ->where('public', true)
  22. ->when($like !== false, function ($query) use ($like) {
  23. $query->where('id', 'like', '%'. $like . '%');
  24. });
  25. });
  26. }
  27. public function scopeNotInRoster($query, $sessionId)
  28. {
  29. return $query->whereNotIn('id', function ($query) use ($sessionId) {
  30. $query->select('jid')
  31. ->from('rosters')
  32. ->where('session_id', $sessionId);
  33. });
  34. }
  35. public function scopeOrderByPresence($query)
  36. {
  37. return $query->leftJoin(DB::raw('(
  38. select min(value) as value, jid
  39. from presences
  40. group by jid) as presences
  41. '), 'presences.jid', '=', 'contacts.id')
  42. ->orderBy('presences.value');
  43. }
  44. public function save(array $options = [])
  45. {
  46. try {
  47. unset($this->photobin);
  48. parent::save($options);
  49. } catch (\Exception $e) {
  50. /*
  51. * Multi processes simultanous save
  52. */
  53. }
  54. }
  55. public function set($vcard, $jid)
  56. {
  57. $this->id = $jid;
  58. $validate_date = Validator::date('Y-m-d');
  59. if (isset($vcard->vCard->BDAY)
  60. && $validate_date->validate($vcard->vCard->BDAY)) {
  61. $this->date = (string)$vcard->vCard->BDAY;
  62. }
  63. if ($vcard->vCard->NICKNAME) {
  64. $this->name = (string)$vcard->vCard->NICKNAME;
  65. }
  66. if ($vcard->vCard->FN) {
  67. $this->fn = (string)$vcard->vCard->FN;
  68. }
  69. if ($vcard->vCard->URL) {
  70. $this->url = (string)$vcard->vCard->URL;
  71. }
  72. if ($vcard->vCard->EMAIL) {
  73. $this->email = (string)$vcard->vCard->EMAIL->USERID;
  74. }
  75. if ($vcard->vCard->ADR) {
  76. $this->adrlocality = (string)$vcard->vCard->ADR->LOCALITY;
  77. $this->adrpostalcode = (string)$vcard->vCard->ADR->PCODE;
  78. $this->adrcountry = (string)$vcard->vCard->ADR->CTRY;
  79. }
  80. if (filter_var((string)$vcard->vCard->PHOTO, FILTER_VALIDATE_URL)
  81. && in_array($this->avatartype, ['vcard-temp', null])) {
  82. $this->photobin = base64_encode(
  83. requestURL((string)$vcard->vCard->PHOTO, 1)
  84. );
  85. $this->avatartype = 'vcard-temp';
  86. } elseif ($vcard->vCard->PHOTO
  87. && in_array($this->avatartype, ['vcard-temp', null])) {
  88. $this->photobin = (string)$vcard->vCard->PHOTO->BINVAL;
  89. $this->avatarhash = sha1(base64_decode($this->photobin));
  90. $this->avatartype = 'vcard-temp';
  91. }
  92. if ($vcard->vCard->DESC) {
  93. $this->description = (string)$vcard->vCard->DESC;
  94. }
  95. }
  96. public function saveBinAvatar()
  97. {
  98. if (!$this->photobin) {
  99. return;
  100. }
  101. $p = new Image;
  102. $p->setKey($this->id);
  103. $p->fromBase($this->photobin);
  104. $p->save();
  105. unset($this->photobin);
  106. }
  107. public function getPicture($size = 'm'): string
  108. {
  109. return getPicture($this->id, $this->id, $size);
  110. }
  111. public function getBanner($size = 'xxl')
  112. {
  113. $banner = !empty($this->id) ? getPicture($this->id . '_banner', $this->id, $size) : null;
  114. return $banner == null ? $this->getPicture($size) : $banner;
  115. }
  116. public function setLocation($item)
  117. {
  118. // Clear
  119. $this->loclatitude = $this->loclongitude = $this->localtitude = $this->loccountry
  120. = $this->loccountrycode = $this->locregion = $this->locpostalcode = $this->loclocality
  121. = $this->locstreet = $this->locbuilding = $this->loctext = $this->locuri
  122. = $this->loctimestamp = null;
  123. // Fill
  124. if ($item->geoloc->lat && isLatitude((float)$item->geoloc->lat)) {
  125. $this->loclatitude = (string)$item->geoloc->lat;
  126. }
  127. if ($item->geoloc->lon && isLongitude((float)$item->geoloc->lon)) {
  128. $this->loclongitude = (string)$item->geoloc->lon;
  129. }
  130. if ($item->geoloc->alt) {
  131. $this->localtitude = (int)$item->geoloc->alt;
  132. }
  133. if ($item->geoloc->country) {
  134. $this->loccountry = (string)$item->geoloc->country;
  135. }
  136. if ($item->geoloc->countrycode) {
  137. $this->loccountrycode = (string)$item->geoloc->countrycode;
  138. }
  139. if ($item->geoloc->region) {
  140. $this->locregion = (string)$item->geoloc->region;
  141. }
  142. if ($item->geoloc->postalcode) {
  143. $this->locpostalcode = (string)$item->geoloc->postalcode;
  144. }
  145. if ($item->geoloc->locality) {
  146. $this->loclocality = (string)$item->geoloc->locality;
  147. }
  148. if ($item->geoloc->street) {
  149. $this->locstreet = (string)$item->geoloc->street;
  150. }
  151. if ($item->geoloc->building) {
  152. $this->locbuilding = (string)$item->geoloc->building;
  153. }
  154. if ($item->geoloc->text) {
  155. $this->loctext = (string)$item->geoloc->text;
  156. }
  157. if ($item->geoloc->uri) {
  158. $this->locuri = (string)$item->geoloc->uri;
  159. }
  160. if ($item->geoloc->timestamp) {
  161. $this->loctimestamp = date(
  162. 'Y-m-d H:i:s',
  163. strtotime((string)$item->geoloc->timestamp)
  164. );
  165. }
  166. }
  167. public function setTune($stanza)
  168. {
  169. $this->tuneartist = (string)$stanza->items->item->tune->artist;
  170. $this->tunelenght = (int)$stanza->items->item->tune->lenght;
  171. $this->tunerating = (int)$stanza->items->item->tune->rating;
  172. $this->tunesource = (string)$stanza->items->item->tune->source;
  173. $this->tunetitle = (string)$stanza->items->item->tune->title;
  174. $this->tunetrack = (string)$stanza->items->item->tune->track;
  175. }
  176. public function setVcard4($vcard)
  177. {
  178. if (isset($vcard->bday->date)
  179. && Validator::date('Y-m-d')->validate($vcard->bday->date)) {
  180. $this->date = (string)$vcard->bday->date;
  181. }
  182. $this->nickname = !empty($vcard->nickname->text)
  183. ? (string)$vcard->nickname->text
  184. : null;
  185. $this->fn = !empty($vcard->fn->text)
  186. ? (string)$vcard->fn->text
  187. : null;
  188. $this->url = !empty($vcard->url->uri)
  189. ? (string)$vcard->url->uri
  190. : null;
  191. if ($this->url == null && $vcard->impp->uri) {
  192. $this->url = $vcard->impp->uri;
  193. }
  194. $this->adrlocality = !empty($vcard->adr->locality)
  195. ? (string)$vcard->adr->locality
  196. : null;
  197. $this->adrcountry = !empty($vcard->adr->locality)
  198. ? (string)$vcard->adr->country
  199. : null;
  200. $this->adrpostalcode = !empty($vcard->adr->code)
  201. ? (string)$vcard->adr->code
  202. : null;
  203. $this->email = !empty($vcard->email->text)
  204. ? (string)$vcard->email->text
  205. : null;
  206. if ($vcard->tel) {
  207. $this->phone = !empty($vcard->tel->uri)
  208. ? substr((string)$vcard->tel->uri, 4)
  209. : null;
  210. // Some clients uses text...
  211. if ($this->phone == null) {
  212. $this->phone = !empty($vcard->tel->text)
  213. ? (string)$vcard->tel->text
  214. : null;
  215. }
  216. }
  217. $this->description = !empty($vcard->note->text)
  218. ? trim((string)$vcard->note->text)
  219. : null;
  220. }
  221. public function getLocationDistanceAttribute(): ?float
  222. {
  223. if (in_array('loctimestamp', $this->attributes) && $this->attributes['loctimestamp'] != null
  224. && \Carbon\Carbon::now()->subDay()->timestamp < strtotime($this->attributes['loctimestamp'])
  225. && $this->attributes['loclatitude'] != null && $this->attributes['loclongitude'] != null) {
  226. $me = User::me()->contact;
  227. if ($me->attributes['loclatitude'] != null && $me->attributes['loclongitude'] != null) {
  228. return getDistance(
  229. $this->attributes['loclatitude'], $this->attributes['loclongitude'],
  230. $me->attributes['loclatitude'], $me->attributes['loclongitude'],
  231. );
  232. }
  233. }
  234. return null;
  235. }
  236. public function getLocationUrlAttribute(): ?string
  237. {
  238. if (array_key_exists('loctimestamp', $this->attributes) && $this->attributes['loctimestamp'] != null
  239. && \Carbon\Carbon::now()->subDay()->timestamp < strtotime($this->attributes['loctimestamp'])
  240. && $this->attributes['loclatitude'] != null && $this->attributes['loclongitude'] != null) {
  241. return 'https://www.openstreetmap.org/'.
  242. '?mlat='.round($this->attributes['loclatitude'], 4).
  243. '&mlon='.round($this->attributes['loclongitude'], 4).
  244. '/#map=13/';
  245. }
  246. return null;
  247. }
  248. public function getTruenameAttribute(): string
  249. {
  250. if ($this->fn) {
  251. return $this->fn;
  252. }
  253. if ($this->nickname) {
  254. return $this->nickname;
  255. }
  256. if ($this->name) {
  257. return $this->name;
  258. }
  259. return explodeJid($this->id)['username'] ?? $this->id;
  260. }
  261. public function getJidAttribute(): ?string
  262. {
  263. return $this->id;
  264. }
  265. public function getAge()
  266. {
  267. if ($this->isValidDate()) {
  268. $age = intval(substr(date('Ymd') - date('Ymd', strtotime($this->date)), 0, -4));
  269. if ($age != 0) {
  270. return $age;
  271. }
  272. }
  273. }
  274. public function getDate()
  275. {
  276. if ($this->date == null) {
  277. return null;
  278. }
  279. $dt = new \DateTime($this->date);
  280. return $dt->format('Y-m-d');
  281. }
  282. public function getSearchTerms()
  283. {
  284. return cleanupId($this->id).'-'.
  285. cleanupId($this->truename).'-'.
  286. cleanupId($this->groupname);
  287. }
  288. public function getBlogUrl()
  289. {
  290. return \Movim\Route::urlize(
  291. 'blog',
  292. ($this->user && isset($this->user->nickname))
  293. ? $this->user->nickname
  294. : $this->id
  295. );
  296. }
  297. public function isBlocked(): bool
  298. {
  299. return \App\User::me()->hasBlocked($this->id, true);
  300. }
  301. public function isEmpty(): bool
  302. {
  303. $this->isValidDate();
  304. return ($this->fn == null
  305. && $this->name == null
  306. && $this->date == null
  307. && $this->url == null
  308. && $this->email == null
  309. && $this->description == null);
  310. }
  311. public function isValidDate(): bool
  312. {
  313. if (isset($this->date)
  314. && $this->date != '0000-00-00T00:00:00+0000'
  315. && $this->date != '1970-01-01 00:00:00'
  316. && $this->date != '1970-01-01 01:00:00'
  317. && $this->date != '1970-01-01T00:00:00+0000') {
  318. return true;
  319. }
  320. $this->date = null;
  321. return false;
  322. }
  323. public function isFromMuc(): bool
  324. {
  325. return strpos($this->jid, '/') !== false;
  326. }
  327. public function isOld(): bool
  328. {
  329. return $this->updated_at !== null
  330. && \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $this->updated_at)->addDay()->isBefore(\Carbon\Carbon::now());
  331. }
  332. public function isMe(): bool
  333. {
  334. return ($this->id == \App\User::me()->id);
  335. }
  336. public function isPublic(): bool
  337. {
  338. $user = \App\User::where('id', $this->id)->first();
  339. return ($user && $user->public);
  340. }
  341. public function hasLocation()
  342. {
  343. return (
  344. array_key_exists('loclatitude', $this->attributes)
  345. && array_key_exists('loclongitude', $this->attributes)
  346. && $this->attributes['loclatitude'] != null
  347. && $this->attributes['loclongitude'] != null);
  348. }
  349. }