yiisoft /
yii-demo
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace App\Blog\Widget; |
||
| 6 | |||
| 7 | use App\Blog\Entity\Post; |
||
| 8 | use Yiisoft\Html\Html; |
||
| 9 | use Yiisoft\Router\UrlGeneratorInterface; |
||
| 10 | use Yiisoft\Yii\Bootstrap5\Widget; |
||
| 11 | |||
| 12 | class PostCard extends Widget |
||
| 13 | { |
||
| 14 | private ?Post $post = null; |
||
| 15 | |||
| 16 | private array $options = []; |
||
| 17 | |||
| 18 | private UrlGeneratorInterface $urlGenerator; |
||
| 19 | |||
| 20 | public function __construct(UrlGeneratorInterface $urlGenerator) |
||
| 21 | { |
||
| 22 | $this->urlGenerator = $urlGenerator; |
||
| 23 | } |
||
| 24 | |||
| 25 | protected function run(): string |
||
| 26 | { |
||
| 27 | if (!isset($this->options['id'])) { |
||
| 28 | $this->options['id'] = "{$this->getId()}-post-card"; |
||
| 29 | } |
||
| 30 | |||
| 31 | $this->initOptions(); |
||
| 32 | |||
| 33 | return implode("\n", [ |
||
| 34 | Html::openTag('div', $this->options), |
||
| 35 | Html::openTag('div', ['class' => 'card-body d-flex flex-column align-items-start']), |
||
| 36 | $this->renderHead(), |
||
| 37 | $this->renderBody(), |
||
| 38 | $this->renderTags(), |
||
| 39 | Html::closeTag('div'), |
||
| 40 | Html::closeTag('div'), |
||
| 41 | ]); |
||
| 42 | } |
||
| 43 | |||
| 44 | protected function renderHead(): string |
||
| 45 | { |
||
| 46 | return Html::a( |
||
| 47 | $this->post->getTitle(), |
||
|
0 ignored issues
–
show
|
|||
| 48 | $this->urlGenerator->generate('blog/post', ['slug' => $this->post->getSlug()]), |
||
| 49 | ['class' => 'mb-0 h4 text-decoration-none'] // stretched-link |
||
| 50 | ) |
||
| 51 | ->render(); |
||
| 52 | } |
||
| 53 | |||
| 54 | protected function renderBody(): string |
||
| 55 | { |
||
| 56 | $return = Html::openTag('div', ['class' => 'card-text mb-auto']); |
||
| 57 | $return .= $this->post->getPublishedAt() === null |
||
| 58 | ? 'not published' |
||
| 59 | : $this->post->getPublishedAt()->format('M, d'); |
||
| 60 | $return .= ' by '; |
||
| 61 | $return .= Html::a( |
||
| 62 | $this->post->getUser()->getLogin(), |
||
| 63 | $this->urlGenerator->generate('user/profile', ['login' => $this->post->getUser()->getLogin()]) |
||
| 64 | )->class('mb-1 text-muted'); |
||
| 65 | |||
| 66 | $return .= Html::p( |
||
| 67 | mb_substr($this->post->getContent(), 0, 400) |
||
| 68 | . (mb_strlen($this->post->getContent()) > 400 ? '…' : '') |
||
| 69 | ); |
||
| 70 | return $return . Html::closeTag('div'); |
||
| 71 | } |
||
| 72 | |||
| 73 | protected function renderTags(): string |
||
| 74 | { |
||
| 75 | $return = Html::openTag('div', ['class' => 'mt-3']); |
||
| 76 | foreach ($this->post->getTags() as $tag) { |
||
| 77 | $return .= Html::a( |
||
| 78 | $tag->getLabel(), |
||
| 79 | $this->urlGenerator->generate('blog/tag', ['label' => $tag->getLabel()]), |
||
| 80 | ['class' => 'btn btn-outline-secondary btn-sm me-2 mt-1'] |
||
| 81 | ); |
||
| 82 | } |
||
| 83 | return $return . Html::closeTag('div'); |
||
| 84 | } |
||
| 85 | |||
| 86 | protected function initOptions(): void |
||
| 87 | { |
||
| 88 | Html::addCssClass($this->options, ['widget' => 'card mb-4']); |
||
| 89 | } |
||
| 90 | |||
| 91 | public function post(?Post $post): self |
||
| 92 | { |
||
| 93 | $this->post = $post; |
||
| 94 | |||
| 95 | if ($post !== null) { |
||
| 96 | $this->options['data']['post-slug'] = $post->getSlug(); |
||
| 97 | } |
||
| 98 | |||
| 99 | return $this; |
||
| 100 | } |
||
| 101 | |||
| 102 | /** |
||
| 103 | * The HTML attributes for the widget container tag. The following special options are recognized. |
||
| 104 | * |
||
| 105 | * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. |
||
| 106 | */ |
||
| 107 | public function options(array $value): self |
||
| 108 | { |
||
| 109 | $this->options = $value; |
||
| 110 | |||
| 111 | return $this; |
||
| 112 | } |
||
| 113 | } |
||
| 114 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.