_host = $host; $this->_board_name = $board_name; $this->_user_entity = $user_entity; } abstract protected function getDetailSelector(array $listInfo): array; //-----------------------필수항목-------------------// final protected function getMySocket(): WebSocket { if ($this->_mySocket === null) { $this->_mySocket = new WebSocket($this->_host); } return $this->_mySocket; } final protected function getMyStorage(): MangboardStorage { if ($this->_myStorage === null) { $this->_myStorage = new MangboardStorage($this->_board_name, $this->_user_entity); } return $this->_myStorage; } final protected function getBoardsEntity(): BoardsEntity { if ($this->_boards_entity === null) { $boardsModel = new BoardsModel(); $this->_boards_entity = $boardsModel->getEntityByID($this->getMyStorage()->getBoardName()); if ($this->_boards_entity === null) { throw new \Exception(__FUNCTION__ . "=> {$this->getMyStorage()->getBoardName()}에 해당 Board 정보가 존재하지 않습니다."); } } return $this->_boards_entity; } final protected function getBoardModel(): BoardModel { if ($this->_board_model === null) { $this->_board_model = new BoardModel("mb_" . $this->getMyStorage()->getBoardName()); } return $this->_board_model; } final protected function getSelector(string $content, string $tag): Crawler { $crawler = new Crawler($content); if ($this->isDebug) { log_message("debug", __FUNCTION__ . "=> " . $tag); } $crawler->filter($tag); if ($this->isDebug) { log_message("debug", sprintf( "\n------------%s HTML-------------\n%s\n-----------------------------------------------------\n", __FUNCTION__, $crawler->filter($tag)->html() )); } return $crawler->filter($tag); } protected function changeURLByCrawler(string $url): string { return preg_match('/^[^?]+/', $url, $matches) ? $matches[0] : null; } protected function getUrlByMediaType(Crawler $node, string $media_tag, string $attr): null|string { switch ($media_tag) { case 'video': $url = $node->attr($attr); // 또는 if ($url === null) { $url = $node->children()->attr("src"); //