media = MediaLibrary::instance(); $this->page = $page; $this->token = $page->access_token; $this->client = new Client([ 'http_errors' => false, 'base_uri' => static::$baseUri ]); } public function clear() { $this->page->delete(); } public function posts(): array { return $this->get( "{$this->page->remote_id}/published_posts", ['fields' => 'id,created_time,full_picture,message,attachments'], 'data', ); } public function saveUrl(string $source, ?string $filename = null): string { $filename = $filename ?: pathinfo(parse_url($source, PHP_URL_PATH), PATHINFO_BASENAME); $file = $this->page->mediaPath.$filename; if (!$this->media->exists($file)) { $this->media->put($file, file_get_contents($source)); Event::fire('media.file.upload', [null, $file, null]); } return $file; } public function saveCover() { $cover = $this->get($this->page->remote_id, ['fields' => 'cover'], 'cover'); $this->page->update([ 'cover' => $this->saveUrl($cover['source']) ]); } public function saveAttachments(Post $post, $data) { foreach($data as $i => $attachment) { $fid = null; switch($attachment['type']) { case 'photo': case 'video_inline': $payload = [ 'href' => $this->saveUrl(data_get($attachment, 'media.image.src')) ]; break; case 'share': case 'event': $fid = $post->id.'-attachment-'.$i; if (!data_get($attachment, 'media.image.src')) { continue 2; } $payload = [ 'href' => $this->saveUrl(data_get($attachment, 'media.image.src'), $fid.'.jpg') ]; break; case 'album': $payload = [ 'href' => $this->saveUrl(data_get($attachment, 'subattachments.data.0.media.image.src')) ]; break; case 'multi_share': $payload = [ 'href' => $this->saveUrl(data_get($attachment, 'subattachments.data.0.media.image.src')) ]; break; case 'native_templates': continue 2; default: throw new \Exception('I dont know how to parse attachment of type '.$attachment['type']); } $fid = $fid ?: data_get($attachment, 'target.id', ''); $post->attachments()->updateOrCreate(['facebook_id' => $fid], array_merge($payload, [ 'facebook_id' => $fid, 'type' => $attachment['type'], ])); } } public function sync(): void { $this->saveCover(); foreach ($this->posts() as $post) { if (!data_get($post, 'message')) { continue; } if (!data_get($post, 'attachments')) { continue; } $payload = [ 'message' => $post['message'], 'facebook_id' => $post['id'], 'href' => data_get($post, 'attachments.data.0.target.url'), 'created_at' => Carbon::parse($post['created_time']), ]; $existing = $this->page->posts()->where('facebook_id', $post['id'])->first(); if ($existing) { $existing->update($payload); } else { $existing = $this->page->posts()->create($payload); } $this->saveAttachments($existing, data_get($post, 'attachments.data')); } if (!is_numeric(Setting::get('max_posts'))) { return; } while ($this->page->posts()->get()->count() > 0 && $this->page->posts()->get()->count() > Setting::get('max_posts')) { $this->page->posts()->orderBy('created_at')->first()->delete(); } } // -------------------------------- static api --------------------------------- // ***************************************************************************** public static function clearAll(): void { foreach (Page::where('type', 'facebook')->get() as $page) { $service = new static($page); $service->clear(); } } public static function syncAll(): void { foreach (Page::where('type', 'facebook')->get() as $page) { $service = new static($page); $service->sync(); } } // -------------------------------- Guzzle Api --------------------------------- // ***************************************************************************** private function get(string $url, array $query = [], ?string $return = null): array { $response = $this->client->get("/{$this->version}/$url", [ 'query' => array_merge($query, ['access_token' => $this->token]), ]); $data = json_decode((string) $response->getBody(), true); return $return === null ? $data : data_get($data, $return); } }