Answer the question
In order to leave comments, you need to log in
How to competently improve your service on Symfony in terms of the OOP approach?
Hello. I am starting to learn Symfony and OOP. Wrote my small test project. But it is felt that there is a g###code.
Help / recommend how to change it, what to fix, so that it is competent from the standpoint of the OOP approach.
The essence of the service: Parsing - collecting news from a news site and immersing them in the database, as well as displaying a list of news. The main question is the literacy of the service structure in terms of the OOP approach
Controller class PostController :
use App\Entity\Post;
use Doctrine\ORM\EntityManagerInterface;
use PHPHtmlParser\Dom;
use GuzzleHttp\Client;
class PostController extends AbstractController
{
private $postRepository;
public function __construct(PostRepository $postRepository)
{
$this->postRepository = $postRepository;
}
/**
* @Route("/", name="posts")
*/
public function index(Request $request, RbcParseClient $parse): Response
{
if ($request->query->get('update') && $request->query->get('update') == '1'){
$parse->updateNews();
}
$posts = $this->postRepository->findLastNews();
return $this->render('post/posts.html.twig', [
'posts' => $posts
]);
}
}
use App\Entity\Post;
use Doctrine\ORM\EntityManagerInterface;
use PHPHtmlParser\Dom;
use GuzzleHttp\Client;
class RbcParseClient
{
private $dom;
private $em;
private $checkPosts;
public function __construct(EntityManagerInterface $em)
{
$this->dom = new Dom();
$this->em = $em;
$postRepository = $this->em->getRepository(Post::class);
$this->checkPosts = $postRepository->findLastNews();
}
public function updateNews(): void
{
$res = self::getUrlContent('https://www.rbc.ru');
$this->dom->load($res);
$contents = $this->dom->find('.news-feed__wrapper .js-news-feed-list')->find('a.news-feed__item');
foreach ($contents as $content)
{
$link = $content->getAttribute('href');
$resDomContent = self::getUrlContent($link);
$this->dom->load($resDomContent);
if (preg_match("/style.rbc/", $link) ) {
$currentNewsItem = new StyleItem($this->dom, $link);
}elseif(preg_match("/agrodigital.rbc/", $link)){
$currentNewsItem = new AgroItem($this->dom, $link);
}else {
$currentNewsItem = new RegularItem($this->dom, $link);
}
$currentNewsItem->parseNewsItem();
$date = self::getItemDate($content);
$currentNewsItem->setDate($date);
$post = new Post();
$position = $date->format('U');
$post->setTitle($currentNewsItem->getTitle());
$post->setBody($currentNewsItem->getBody());
$post->setImage($currentNewsItem->getImage());
$post->setLink($currentNewsItem->getLink());
$post->setCreatedAt($date);
$post->setPosition($position);
$this->em->persist($post);
}
$this->em->flush();
}
public static function getItemDate(Dom\HtmlNode $content): \DateTime
{
$dateInfo = $content
->find('.news-feed__item__date .news-feed__item__date-text')->innerHTML;
$time = explode(" ", $dateInfo)[1];
$date = new \DateTime("now");
$timeSet = explode(":",$time);
$date->setTime((int)$timeSet[0], (int)$timeSet[1]);
return $date;
}
public static function getUrlContent(string $url): string
{
$client = new Client([ 'base_uri' => $url ]);
$response = $client->request('GET');
$res = $response->getBody();
return $res;
}
}
use PHPHtmlParser\Dom;
class RegularItem extends AbstractParseManager
{
public function parseNewsItem(): void
{
if ($this->dom->find(".js-rbcslider")[0]) {
$this->parseTitle();
$this->parseImg();
$this->parseContent();
}else{
$this->title = $this->image = $this->body = "";
}
}
private function parseTitle(): void
{
try {
$artTitle = $this->dom->find(".js-rbcslider")[0]->find('.article__header .article__header__title .js-slide-title')->innerHtml;
$this->title = $artTitle;
}catch(\Exception $e){
$this->title = "";
}
}
private function parseImg(){
try {
$artImg = $this->dom->find(".js-rbcslider")[0]->find('.article__text .article__main-image img');
$this->image = $artImg->getAttribute('src');
}catch(\Exception $e){
$this->image = "";
}
}
private function parseContent(){
try {
$artContents = $this->dom->find(".js-rbcslider")[0]->find('.article .article__text');
$html = "";
$domContent = new Dom();
foreach ($artContents as $content)
{
$domContent->load($content);
$artStrings = $domContent->find("p");
foreach ($artStrings as $string) {
$str = strip_tags($string->innerHtml);
$html .= "<br />" . trim($str);
}
}
$this->body = $html;
}catch(\Exception $e){
$this->body = "";
}
}
}
use PHPHtmlParser\Dom;
abstract class AbstractParseManager
{
protected $title;
protected $image;
protected $body;
protected $link;
protected $date;
protected $dom;
public function __construct(Dom $dom, string $link)
{
$this->link = $link;
$this->dom = $dom;
}
abstract public function parseNewsItem(): void ;
public function getTitle()
{
return $this->title;
}
public function getBody()
{
return $this->body;
}
public function getImage()
{
return $this->image;
}
public function getLink()
{
return $this->link;
}
public function getDate()
{
return $this->date;
}
public function setDate(\DateTime $date): void
{
$this->date = $date;
}
}
use App\Entity\Post;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
class PostRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Post::class);
}
public function findLastNews()
{
return $this->createQueryBuilder('p')
->orderBy('p.position', 'DESC')
->setMaxResults(15)
->getQuery()
->getResult()
;
}
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question