diff --git a/app/Drupal/external_content/src/Builder/RenderArrayBuilderManager.php b/app/Drupal/external_content/src/Builder/RenderArrayBuilderManager.php index d786fb4c..998ec0aa 100644 --- a/app/Drupal/external_content/src/Builder/RenderArrayBuilderManager.php +++ b/app/Drupal/external_content/src/Builder/RenderArrayBuilderManager.php @@ -23,7 +23,7 @@ public function __construct( #[\Override] public function build(NodeInterface $node, EnvironmentInterface $environment): RenderArrayBuilderResult { - // @todo Build context DTO is heavily needed here. In cases where same + // @todo Build scope DTO is heavily needed here. In cases where same // environment can be rendered in more than one view mode it can be // helpful. $this->childRenderArrayBuilder->setEnvironment($environment); diff --git a/app/Drupal/external_content/src/Extension/BasicHtmlExtension.php b/app/Drupal/external_content/src/Extension/BasicHtmlExtension.php index ea8ac58e..2156d18f 100644 --- a/app/Drupal/external_content/src/Extension/BasicHtmlExtension.php +++ b/app/Drupal/external_content/src/Extension/BasicHtmlExtension.php @@ -10,9 +10,6 @@ /** * Provides a very basic extension with most useful settings. - * - * @todo Consider creating dedicated extensions for plain text, code and - * element, and use them here. */ final class BasicHtmlExtension implements ExtensionInterface { @@ -22,13 +19,9 @@ public function __construct( #[\Override] public function register(EnvironmentBuilderInterface $environment): void { - $html_parser_manager = $this - ->externalContentManager - ->getHtmlParserManager(); + $html_parser_manager = $this->externalContentManager->getHtmlParserManager(); $serializer_manager = $this->externalContentManager->getSerializerManager(); - $render_array_builder_manager = $this - ->externalContentManager - ->getRenderArrayBuilderManager(); + $render_array_builder_manager = $this->externalContentManager->getRenderArrayBuilderManager(); $environment ->addHtmlParser($html_parser_manager->get('plain_text')) diff --git a/app/Drupal/external_content/tests/src/Unit/Builder/ElementRenderArrayBuilderTest.php b/app/Drupal/external_content/tests/src/Unit/Builder/ElementRenderArrayBuilderTest.php index 36a4260e..da94dfcc 100644 --- a/app/Drupal/external_content/tests/src/Unit/Builder/ElementRenderArrayBuilderTest.php +++ b/app/Drupal/external_content/tests/src/Unit/Builder/ElementRenderArrayBuilderTest.php @@ -15,7 +15,6 @@ /** * @covers \Drupal\external_content\Builder\ElementRenderArrayBuilder * @group external_content - * @todo Make it kernel with a proper testing of 'pre_render'. */ final class ElementRenderArrayBuilderTest extends UnitTestCaseTest { diff --git a/app/Drupal/laszlo/components/content/article-card/article-card.css b/app/Drupal/laszlo/components/content/article-card/article-card.css index df6c23f9..aed61b26 100644 --- a/app/Drupal/laszlo/components/content/article-card/article-card.css +++ b/app/Drupal/laszlo/components/content/article-card/article-card.css @@ -33,6 +33,7 @@ overflow: hidden; flex-shrink: 0; align-self: center; + width: 150px; border-radius: var(--spacing-2); box-shadow: var(--elevation-1); diff --git a/app/Drupal/laszlo/components/content/article/article.css b/app/Drupal/laszlo/components/content/article/article.css index d0a9678c..7737fe76 100644 --- a/app/Drupal/laszlo/components/content/article/article.css +++ b/app/Drupal/laszlo/components/content/article/article.css @@ -62,7 +62,7 @@ .article__poster { overflow: hidden; flex-shrink: 0; - min-width: 200px; + width: 200px; border-radius: var(--spacing-2); box-shadow: var(--elevation-2); margin-inline: auto; diff --git a/app/Drupal/laszlo/components/ui/image/image.component.yml b/app/Drupal/laszlo/components/ui/image/image.component.yml index 5e29779b..180fbe6e 100644 --- a/app/Drupal/laszlo/components/ui/image/image.component.yml +++ b/app/Drupal/laszlo/components/ui/image/image.component.yml @@ -15,10 +15,10 @@ props: type: string width: title: Image width - type: [string, integer ] + type: [string, integer, 'null'] height: title: Image height - type: [string, integer] + type: [string, integer, 'null'] alt: title: Image alt type: string @@ -29,6 +29,13 @@ props: - lazy type: string default: lazy + decoding: + title: Image decoding + enum: + - sync + - async + - auto + type: string srcset: title: Image srcset type: array diff --git a/app/Drupal/laszlo/components/ui/image/image.twig b/app/Drupal/laszlo/components/ui/image/image.twig index b3d7a830..cf9c6c8b 100644 --- a/app/Drupal/laszlo/components/ui/image/image.twig +++ b/app/Drupal/laszlo/components/ui/image/image.twig @@ -3,6 +3,7 @@ {% do height ? attributes.setAttribute('height', height) %} {% do attributes.setAttribute('src', src) %} {% do attributes.setAttribute('loading', loading|default('lazy')) %} +{% do decoding ? attributes.setAttribute('decoding', decoding) %} {% if srcset is not empty %} {% do attributes.setAttribute('sizes', sizes|default('100vw')|join(', ')) %} {% set srcset_array = [] %} diff --git a/app/Drupal/laszlo/composer.json b/app/Drupal/laszlo/composer.json index 6f2cfc28..545a68c6 100644 --- a/app/Drupal/laszlo/composer.json +++ b/app/Drupal/laszlo/composer.json @@ -2,6 +2,11 @@ "name": "niklan/laszlo", "type": "drupal-custom-theme", "version": "1.0.0-dev", + "autoload": { + "psr-4": { + "Drupal\\laszlo\\": "src" + } + }, "require": { "niklan/niklan": "^1.0@dev", "niklan-asset/lora": "^35" diff --git a/app/Drupal/laszlo/templates/field/field-with-common-markup.twig b/app/Drupal/laszlo/templates/field/field-with-common-markup.twig deleted file mode 100644 index 613837fe..00000000 --- a/app/Drupal/laszlo/templates/field/field-with-common-markup.twig +++ /dev/null @@ -1,24 +0,0 @@ -{# -/** - * @file - * Predefined template for field with common markup and wrappers. - * - * This template provides a common classes for each wrapper: - * - Main wrapper: - * - "field field_name_[field-name] field_type_[field-type] field_label_[label-position]" - * - Label wrapper: - * - "field__label" - * - Single value wrapper: - * - "field__value" - * - Multi-value wrapper: - * - "field__items" - * - Multi-value item wrapper: - * - "field__item" - * - * Usage: You can use it in any field*.html.twig template: - * @code - * {{ include('@laszlo/field/field-with-common-markup.twig') }} - * @endcode - */ -#} -@TODO diff --git a/app/Drupal/laszlo/templates/field/field-with-entity-markup.twig b/app/Drupal/laszlo/templates/field/field-with-entity-markup.twig deleted file mode 100644 index 1f53693c..00000000 --- a/app/Drupal/laszlo/templates/field/field-with-entity-markup.twig +++ /dev/null @@ -1,24 +0,0 @@ -{# -/** - * @file - * Predefined template for field with entity specific markup and wrappers. - * - * This template provides entity specific classes for each wrapper: - * - Main wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]" - * - Label wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__label" - * - Single value wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__value" - * - Multi-value wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__items" - * - Multi-value item wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__item" - * - * Usage: You can use it in any field*.html.twig template: - * @code - * {{ include('@laszlo/field/field-with-entity-markup.twig') }} - * @endcode - */ -#} -@TODO diff --git a/app/Drupal/laszlo/templates/field/field-with-full-markup.twig b/app/Drupal/laszlo/templates/field/field-with-full-markup.twig deleted file mode 100644 index f0319b45..00000000 --- a/app/Drupal/laszlo/templates/field/field-with-full-markup.twig +++ /dev/null @@ -1,30 +0,0 @@ -{# -/** - * @file - * Predefined template for field with full markup and wrappers. - * - * By default this template provides both, entity specific and common classes - * for each wrapper: - * - Main wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]" - * - "field field--name--[field-name] field--type--[field-type] field--label--[label-position]" - * - Label wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__label" - * - "field__label" - * - Single value wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__value" - * - "field__value" - * - Multi-value wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__items" - * - "field__items" - * - Multi-value item wrapper: - * - "[entity-type-id]-[entity-bundle]-[field-name]__item" - * - "field__item" - * - * Usage: You can use it in any field*.html.twig template: - * @code - * {{ include('@laszlo/field/field-with-full-markup.twig') }} - * @endcode - */ -#} -@TODO diff --git a/app/Drupal/laszlo/templates/form/input--checkbox.html.twig b/app/Drupal/laszlo/templates/form/input--checkbox.html.twig index 7dc04d07..94685049 100644 --- a/app/Drupal/laszlo/templates/form/input--checkbox.html.twig +++ b/app/Drupal/laszlo/templates/form/input--checkbox.html.twig @@ -13,7 +13,7 @@ * @ingroup themeable */ #} -@TODO complete +@TODO Complete it. {% embed 'laszlo:checkbox' with input_props only %} {% endembed %} diff --git a/app/Drupal/niklan/config/schema/niklan.schema.yml b/app/Drupal/niklan/config/schema/niklan.schema.yml index f6ea6f34..02578556 100644 --- a/app/Drupal/niklan/config/schema/niklan.schema.yml +++ b/app/Drupal/niklan/config/schema/niklan.schema.yml @@ -1,21 +1,3 @@ filter_settings.niklan_markdown: type: filter label: 'Markdown filter' - -field.formatter.settings.niklan_responsive_media_thumbnail: - type: mapping - label: Responsive media thumbnail - mapping: - responsive_image_style: - type: string - label: 'Responsive image style' - image_link: - type: string - label: 'Link image to' - image_loading: - type: mapping - label: 'Image loading settings' - mapping: - attribute: - type: string - label: 'Loading attribute' \ No newline at end of file diff --git a/app/Drupal/niklan/niklan.module b/app/Drupal/niklan/niklan.module index 0c38024f..be43eca0 100755 --- a/app/Drupal/niklan/niklan.module +++ b/app/Drupal/niklan/niklan.module @@ -3,18 +3,13 @@ declare(strict_types=1); use Drupal\comment\CommentInterface; -use Drupal\Component\Utility\Html; -use Drupal\Core\Ajax\AjaxResponse; -use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Image\ImageFactory; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\StringTranslation\TranslatableMarkup; -use Drupal\image\Entity\ImageStyle; use Drupal\niklan\Hook\Entity\BaseFieldInfo; use Drupal\niklan\Hook\Entity\BundleInfoAlter; use Drupal\niklan\Hook\Entity\CommentInsert; @@ -25,36 +20,12 @@ use Drupal\niklan\Hook\Theme\PreprocessPager; use Drupal\niklan\Hook\Token\TokenInfo; use Drupal\niklan\Hook\Token\Tokens; use Drupal\niklan\Hook\Toolbar\ContentEditingToolbar; -use Drupal\responsive_image\Entity\ResponsiveImageStyle; -use Drupal\responsive_image\ResponsiveImageStyleInterface; /** * Implements hook_theme(). */ function niklan_theme(array $existing, string $type, string $theme, string $path): array { return [ - 'niklan_follow' => [ - 'variables' => [], - ], - 'niklan_previous_next' => [ - 'variables' => [ - 'previous_url' => NULL, - 'previous_label' => NULL, - 'next_url' => NULL, - 'next_label' => NULL, - ], - ], - 'niklan_share' => [ - 'variables' => [ - 'url' => NULL, - 'text' => NULL, - ], - ], - 'niklan_toc' => [ - 'variables' => [ - 'links' => NULL, - ], - ], 'niklan_contact' => [ 'variables' => [ 'description' => NULL, @@ -62,32 +33,12 @@ function niklan_theme(array $existing, string $type, string $theme, string $path 'telegram' => NULL, ], ], - 'niklan_form_success' => [ - 'variables' => [ - 'title' => NULL, - 'message' => NULL, - ], - ], - 'niklan_copyright' => [ - 'variables' => [ - 'attributes' => [], - ], - ], 'niklan_support' => [ 'variables' => [ 'description' => NULL, 'donate_url' => NULL, ], ], - 'niklan_last_content' => [ - 'variables' => [ - 'attributes' => [], - 'items' => [], - 'title' => NULL, - 'more_url' => NULL, - 'more_label' => NULL, - ], - ], 'niklan_about' => [ 'variables' => [ 'photo_uri' => NULL, @@ -103,32 +54,12 @@ function niklan_theme(array $existing, string $type, string $theme, string $path 'hourly_rate' => NULL, ], ], - 'niklan_mobile_header_bar' => [ - 'variables' => [ - 'logo' => NULL, - ], - ], 'niklan_comment_list' => [ 'variables' => [ 'heading' => NULL, 'items' => [], ], ], - 'niklan_media_attached_file' => [ - 'variables' => [ - 'attributes' => [], - 'uri' => NULL, - 'filename' => NULL, - 'filesize' => NULL, - 'label' => NULL, - ], - ], - 'niklan_oembed_video' => [ - 'variables' => [ - 'preview' => NULL, - 'content' => NULL, - ], - ], 'niklan_blog_list' => [ 'variables' => [ 'items' => [], @@ -150,22 +81,11 @@ function niklan_theme(array $existing, string $type, string $theme, string $path 'pager' => NULL, ], ], - 'niklan_blog_meta' => [ - 'variables' => [ - 'created' => NULL, - 'comment_count' => NULL, - 'comments_url' => NULL, - 'estimated_read_time' => NULL, - ], - ], 'niklan_tag_list' => [ 'variables' => [ 'items' => [], ], ], - 'niklan_sidebar_search_form' => [ - 'variables' => [], - ], 'niklan_lightbox_responsive_image' => [ 'variables' => [ 'uri' => NULL, @@ -226,28 +146,6 @@ function niklan_theme(array $existing, string $type, string $theme, string $path ]; } -/** - * Implements hook_contact_tools_ajax_response_alter(). - * - * Allows modules to alter AJAX response handled by the module. You can fully - * alter, remove and add new commands to response. - */ -function niklan_contact_tools_ajax_response_alter(AjaxResponse &$ajax_response, array $form, FormStateInterface $form_state): void { - if (!$form_state->isExecuted()) { - return; - } - - $class_name = '.' . Html::getClass($form['#form_id'] . '-contact-tools-processed'); - - $message = new TranslatableMarkup('Thank you, your message was successfully sent.'); - $thanks = [ - '#theme' => 'niklan_form_success', - '#title' => new TranslatableMarkup('Successful!'), - '#message' => $message, - ]; - $ajax_response->addCommand(new ReplaceCommand($class_name, $thanks)); -} - /** * Implements hook_preprocess_HOOK(). */ @@ -264,51 +162,6 @@ function niklan_toolbar(): array { ); } -/** - * Implements hook_preprocess_HOOK() for 'responsive-image.html.twig'. - */ -function niklan_preprocess_responsive_image(array &$variables): void { - // This hook is also set width and height required by default lazy loading - // implementation. But this one called after, so with and height is not set - // at the point when default lazy is added, so we force it. - $variables['img_element']['#attributes']['loading'] = 'lazy'; - $variables['img_element']['#attributes']['decoding'] = 'async'; - - $responsive_style = ResponsiveImageStyle::load( - $variables['responsive_image_style_id'], - ); - - if (!$responsive_style instanceof ResponsiveImageStyleInterface) { - return; - } - - $image_factory = Drupal::service('image.factory'); - assert($image_factory instanceof ImageFactory); - $fallback_style = ImageStyle::load( - $responsive_style->getFallbackImageStyle(), - ); - - if (!$fallback_style instanceof ImageStyle) { - return; - } - - $fallback_image = $fallback_style->buildUri($variables['uri']); - $image_factory->get($fallback_image); - $variables['img_element']['#attributes']['width'] = $image_factory - ->get($fallback_image) - ->getWidth(); - $variables['img_element']['#attributes']['height'] = $image_factory - ->get($fallback_image) - ->getHeight(); -} - -/** - * Implements hook_preprocess_HOOK() for 'image.html.twig'. - */ -function niklan_preprocess_image(array &$variables): void { - $variables['attributes']['decoding'] = 'async'; -} - /** * Implements hook_field_widget_WIDGET_TYPE_form_alter() for text_textarea. */ diff --git a/app/Drupal/niklan/src/Element/LastBlogPosts.php b/app/Drupal/niklan/src/Element/LastBlogPosts.php deleted file mode 100644 index e9e3a0ce..00000000 --- a/app/Drupal/niklan/src/Element/LastBlogPosts.php +++ /dev/null @@ -1,100 +0,0 @@ -entityTypeManager = $container->get('entity_type.manager'); - - return $instance; - } - - #[\Override] - public function getInfo(): array { - return [ - '#theme' => 'niklan_last_content', - '#limit' => 3, - '#view_mode' => 'teaser', - '#title' => new TranslatableMarkup('Last blog posts'), - '#more_url' => Url::fromRoute('niklan.blog_list'), - '#more_label' => new TranslatableMarkup('All posts'), - '#pre_render' => [ - [$this, 'preRenderElement'], - ], - ]; - } - - public function preRenderElement(array $element): array { - $this->limit = $element['#limit']; - $this->viewMode = $element['#view_mode']; - - $items = $this->prepareResults(); - - // Do not render element if no blog posts found. - if (!$items) { - return []; - } - - $element['#items'] = $items; - - return $element; - } - - protected function prepareResults(): array { - $results = []; - $ids = $this->findResults(); - - if (!$ids) { - return $results; - } - - $storage = $this->entityTypeManager->getStorage('node'); - $view_builder = $this->entityTypeManager->getViewBuilder('node'); - $entities = $storage->loadMultiple($ids); - - foreach ($entities as $entity) { - $results[] = $view_builder->view($entity, $this->viewMode); - } - - return $results; - } - - protected function findResults(): array { - $query = $this - ->entityTypeManager - ->getStorage('node') - ->getQuery() - ->accessCheck(FALSE); - - $query - ->condition('type', 'blog_entry') - ->condition('status', NodeInterface::PUBLISHED) - ->sort('created', 'DESC') - ->range(0, $this->limit); - - return $query->execute(); - } - -} diff --git a/app/Drupal/niklan/src/Element/OEmbedVideo.php b/app/Drupal/niklan/src/Element/OEmbedVideo.php deleted file mode 100644 index efb0339a..00000000 --- a/app/Drupal/niklan/src/Element/OEmbedVideo.php +++ /dev/null @@ -1,224 +0,0 @@ -oEmbedFetcher = $container->get('media.oembed.resource_fetcher'); - $instance->oEmbedResolver = $container->get('media.oembed.url_resolver'); - $instance->configFactory = $container->get('config.factory'); - $instance->iFrameUrlHelper = $container - ->get('media.oembed.iframe_url_helper'); - $instance->responsiveImageStyleStorage = $container - ->get('entity_type.manager') - ->getStorage('responsive_image_style'); - - return $instance; - } - - #[\Override] - public function getInfo(): array { - return [ - '#theme' => 'niklan_oembed_video', - '#media' => NULL, - '#preview_responsive_image_style' => NULL, - '#pre_render' => [ - [$this, 'preRenderOembedVideo'], - ], - ]; - } - - public function preRenderOembedVideo(array $element): array { - if (!$this->validateElement($element)) { - return []; - } - - $element['#preview'] = $this->buildPreview($element); - $element['#content'] = $this->buildContent($element); - - return $element; - } - - protected function validateElement(array $element): bool { - $media = $element['#media']; - - if (!$media instanceof MediaInterface) { - return FALSE; - } - - if ($media->getSource()->getPluginId() !== 'oembed:video') { - return FALSE; - } - - $video_url = $media->getSource()->getSourceFieldValue($media); - - if (!\is_string($video_url)) { - return FALSE; - } - - // There is no need to continue if resource didn't respond for some reason. - if (!$this->validateResource($video_url)) { - return FALSE; - } - - return $this->validateResponsiveImageStyle($element); - } - - protected function buildPreview(array $element): array { - $media = $element['#media']; - \assert($media instanceof MediaInterface); - - return [ - '#theme' => 'responsive_image_formatter', - '#responsive_image_style_id' => $element['#preview_responsive_image_style'], - '#item' => $media->get('thumbnail')->first(), - '#item_attributes' => [], - '#cache' => [ - 'tags' => $media->getCacheTags(), - ], - ]; - } - - protected function buildContent(array $element): array { - $media = $element['#media']; - \assert($media instanceof MediaInterface); - - $video_url = $media->getSource()->getSourceFieldValue($media); - \assert(\is_string($video_url)); - $resource_url = $this->oEmbedResolver->getResourceUrl($video_url); - $resource = $this->oEmbedFetcher->fetchResource($resource_url); - $iframe_url = $this->buildIframeUrl($video_url, $resource); - - return $this->buildIframe($iframe_url->toString(), (int) $resource->getWidth(), (int) $resource->getHeight(), $resource->getTitle()); - } - - protected function validateResource(string $video_url): bool { - try { - $resource_url = $this->oEmbedResolver->getResourceUrl($video_url); - $this->oEmbedFetcher->fetchResource($resource_url); - - return TRUE; - } - catch (ResourceException) { - return FALSE; - } - } - - protected function validateResponsiveImageStyle(array $element): bool { - if (!$element['#preview_responsive_image_style']) { - return FALSE; - } - - $responsive_image_style = $this->responsiveImageStyleStorage->load( - $element['#preview_responsive_image_style'], - ); - - if (!$responsive_image_style instanceof ResponsiveImageStyleInterface) { - return FALSE; - } - - // Make sure this image style has mapping, without it is useless. - return $responsive_image_style->hasImageStyleMappings(); - } - - protected function buildIframeUrl(string $video_url, Resource $resource): Url { - if ($resource->getProvider()?->getName() === 'YouTube') { - // Default controller 'media.oembed_iframe' is not used because YouTube - // oembed provider returns iframe markup without allowing us to add - // special query parameters like autoplay. Also, YouTube doesn't return - // URL for that iframe. - $video_id = $this->parseYouTubeVideoId($video_url); - $url = Url::fromUri("https://www.youtube.com/embed/{$video_id}", [ - 'query' => [ - 'autoplay' => 1, - ], - ]); - } - else { - $url = Url::fromRoute('media.oembed_iframe', [], [ - 'query' => [ - 'url' => $video_url, - 'hash' => $this->iFrameUrlHelper->getHash($video_url, 0, 0), - ], - ]); - - $domain = $this->configFactory->get('media.settings')->get('iframe_domain'); - - if ($domain) { - $url->setOption('base_url', $domain); - } - } - - return $url; - } - - protected function buildIframe(string $src, int $width, int $height, ?string $title): array { - $element = [ - '#type' => 'html_tag', - '#tag' => 'iframe', - '#attributes' => [ - 'src' => $src, - 'frameborder' => 0, - 'scrolling' => FALSE, - 'allowtransparency' => TRUE, - 'allow' => 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture', - 'allowfullscreen' => TRUE, - 'width' => $width, - 'height' => $height, - 'class' => ['media-oembed-content'], - ], - '#attached' => [ - 'library' => [ - 'media/oembed.formatter', - ], - ], - ]; - - if ($title) { - $element['#attributes']['title'] = $title; - } - - return $element; - } - - protected function parseYouTubeVideoId(string $url): ?string { - \preg_match( - "/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'<> ]+)/", - $url, - $matches, - ); - - return $matches[1] ?? NULL; - } - -} diff --git a/app/Drupal/niklan/src/Element/PreviousNext.php b/app/Drupal/niklan/src/Element/PreviousNext.php deleted file mode 100644 index 09de8fb6..00000000 --- a/app/Drupal/niklan/src/Element/PreviousNext.php +++ /dev/null @@ -1,108 +0,0 @@ -entityTypeManager = $container->get('entity_type.manager'); - - return $instance; - } - - #[\Override] - public function getInfo(): array { - return [ - '#theme' => 'niklan_previous_next', - '#entity' => NULL, - '#pre_render' => [ - [$this, 'prepareLinks'], - ], - ]; - } - - public function prepareLinks(array $element): array { - $entity = $element['#entity']; - - if (!$entity instanceof ContentEntityInterface) { - return []; - } - - $cache = new CacheableMetadata(); - $cache->addCacheableDependency($entity); - - $previous_entity = $this->findPrevious($entity); - - if ($previous_entity) { - $element['#previous_url'] = $previous_entity->toUrl()->toString(); - $element['#previous_label'] = $previous_entity->label(); - $cache->addCacheableDependency($previous_entity); - } - - $next_entity = $this->findNext($entity); - - if ($next_entity) { - $element['#next_url'] = $next_entity->toUrl()->toString(); - $element['#next_label'] = $next_entity->label(); - $cache->addCacheableDependency($next_entity); - } - - $cache->applyTo($element); - - return $element; - } - - protected function findPrevious(EntityInterface $entity): ?EntityInterface { - if (!\method_exists($entity, 'getCreatedTime')) { - return NULL; - } - - $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); - $id = $storage->getQuery() - ->accessCheck(FALSE) - ->condition('type', $entity->bundle()) - ->condition('created', $entity->getCreatedTime(), '>') - ->range(0, 1) - ->sort('created') - ->execute(); - - return $id ? $storage->load(\reset($id)) : NULL; - } - - protected function findNext(EntityInterface $entity): ?EntityInterface { - if (!\method_exists($entity, 'getCreatedTime')) { - return NULL; - } - - $storage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); - $id = $storage->getQuery() - ->accessCheck(FALSE) - ->condition('type', $entity->bundle()) - ->condition('created', $entity->getCreatedTime(), '<') - ->range(0, 1) - ->sort('created', 'DESC') - ->execute(); - - return $id ? $storage->load(\reset($id)) : NULL; - } - -} diff --git a/app/Drupal/niklan/src/ExternalContent/Asset/AssetManager.php b/app/Drupal/niklan/src/ExternalContent/Asset/AssetManager.php index 00e696e8..d333dcfc 100644 --- a/app/Drupal/niklan/src/ExternalContent/Asset/AssetManager.php +++ b/app/Drupal/niklan/src/ExternalContent/Asset/AssetManager.php @@ -8,6 +8,7 @@ use Drupal\Component\Utility\UrlHelper; use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\File\FileExists; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\file\FileUsage\FileUsageInterface; @@ -112,8 +113,38 @@ private function syncWithFile(string $path): ?FileInterface { return $this->saveToFile($path); } - /* @phpstan-ignore-next-line */ - return $file_storage->load(\reset($file_ids)); + $file = $file_storage->load(\reset($file_ids)); + + if (!$file instanceof FileInterface) { + return NULL; + } + + $this->ensureFileIsPresented($file, $path); + + return $file; + } + + /** + * Ensures the file is presented. + * + * It is mostly for the local environment, when the file entities are present + * in the database, but the physically files are missing. This method copies + * the file in that case to make sure they are in sync. + */ + private function ensureFileIsPresented(FileInterface $file, string $path): void { + $file_uri = $file->getFileUri(); + + if (!\is_string($file_uri) || \file_exists($file_uri)) { + return; + } + + $destination = \pathinfo($file_uri, \PATHINFO_DIRNAME); + + if (!$this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { + return; + } + + $this->fileSystem->copy($path, $file_uri, FileExists::Replace); } private function createMediaForFile(FileInterface $file): ?MediaInterface { diff --git a/app/Drupal/niklan/src/ExternalContent/Extension/Blog.php b/app/Drupal/niklan/src/ExternalContent/Extension/Blog.php index 5d5282ca..52d049f9 100644 --- a/app/Drupal/niklan/src/ExternalContent/Extension/Blog.php +++ b/app/Drupal/niklan/src/ExternalContent/Extension/Blog.php @@ -38,8 +38,6 @@ public function register(EnvironmentBuilderInterface $environment): void { $parser_manager = $this->externalContentManager->getHtmlParserManager(); $environment - // @todo Consider to replace by callable subscribers right here. Look - // like there are no need for Drupal's event dispatcher. ->setEventDispatcher($this->eventDispatcher) ->addExtension($extension_manager->get('file_finder')) ->addExtension($extension_manager->get('basic_html')) diff --git a/app/Drupal/niklan/src/ExternalContent/Loader/Blog.php b/app/Drupal/niklan/src/ExternalContent/Loader/Blog.php index e8fece62..5d4e5ae0 100644 --- a/app/Drupal/niklan/src/ExternalContent/Loader/Blog.php +++ b/app/Drupal/niklan/src/ExternalContent/Loader/Blog.php @@ -66,7 +66,9 @@ public function load(IdentifiedSourceBundle $bundle): LoaderResult { $this->syncBlogEntryVariation($blog_entry, $identified_source); } - // @todo Add some checks to avoid unnecessary saving. + // @todo Add some checks to avoid unnecessary saving. Seems like it safe to + // compare "updated" + some loader version. If logic or content is changed + // only then update it. But it should allow force import for dev purpose. $blog_entry->save(); $this->logger->info(\sprintf( 'External content bundle %s synced with node:%s', @@ -403,13 +405,14 @@ private function processImageSource(Element $node, string $source_dir): string { private function createDrupalMediaImageNode(Element $node, MediaInterface $media): DrupalMedia { \assert(\is_string($media->uuid())); + $attributes = $node->getAttributes(); return new DrupalMedia( type: 'image', uuid: $media->uuid(), data: new Data([ - 'alt' => $node->getAttributes()->getAttribute('alt'), - 'title' => $node->getAttributes()->getAttribute('title'), + 'alt' => $attributes->getAttribute('alt'), + 'title' => $attributes->hasAttribute('title') ? $attributes->getAttribute('title') : $attributes->getAttribute('alt'), ]), ); } @@ -460,7 +463,6 @@ private function prepareExternalContentLink(Element $node, string $pathname): vo $url = \str_replace( search: $external_content_dir, // Since GitHub is requiring that part, it is forced here. - // @todo Think how it can be improved to handle without hardcoding. replace: "$repository_url/tree/main", subject: $pathname, ); diff --git a/app/Drupal/niklan/src/ExternalContent/RenderArrayBuilder/Link.php b/app/Drupal/niklan/src/ExternalContent/RenderArrayBuilder/Link.php index cbcd314b..82e29e1b 100644 --- a/app/Drupal/niklan/src/ExternalContent/RenderArrayBuilder/Link.php +++ b/app/Drupal/niklan/src/ExternalContent/RenderArrayBuilder/Link.php @@ -63,6 +63,11 @@ public function supportsBuild(NodeInterface $node): bool { } $attributes = $node->getAttributes(); + + if (!$attributes->hasAttribute('data-selector')) { + return FALSE; + } + $is_link = $node->getTag() === 'a'; $is_external_link = $attributes->getAttribute('data-selector') === 'niklan:external-link'; $is_has_md5 = $attributes->hasAttribute('data-pathname-md5'); diff --git a/app/Drupal/niklan/src/ExternalContent/Serializer/AlertSerializer.php b/app/Drupal/niklan/src/ExternalContent/Serializer/AlertSerializer.php index 3978d0e9..b6bebb1f 100644 --- a/app/Drupal/niklan/src/ExternalContent/Serializer/AlertSerializer.php +++ b/app/Drupal/niklan/src/ExternalContent/Serializer/AlertSerializer.php @@ -60,7 +60,7 @@ public function deserialize(Data $data, string $stored_version, ChildSerializerI * } $values */ $values = $data->all(); - $heading = $values['heading'] + $heading = isset($values['heading']) ? $child_serializer->deserialize($values['heading']) : NULL; $alert = new Alert($values['type'], $heading); diff --git a/app/Drupal/niklan/src/ExternalContent/Utils/TocBuilder.php b/app/Drupal/niklan/src/ExternalContent/Utils/TocBuilder.php index 60cf312c..2a8de783 100644 --- a/app/Drupal/niklan/src/ExternalContent/Utils/TocBuilder.php +++ b/app/Drupal/niklan/src/ExternalContent/Utils/TocBuilder.php @@ -43,7 +43,13 @@ protected function processNode(NodeInterface $node, array &$headings): void { $this->recursiveGetHeadings($node, $headings); } - if (!($node instanceof Element) || $node->getTag() !== 'a' || $node->getAttributes()->getAttribute('class') !== 'heading-permalink') { + if (!$node instanceof Element || $node->getTag() !== 'a') { + return; + } + + $attributes = $node->getAttributes(); + + if (!$attributes->hasAttribute('class') || $attributes->getAttribute('class') !== 'heading-permalink') { return; } diff --git a/app/Drupal/niklan/src/Node/Entity/BlogEntryInterface.php b/app/Drupal/niklan/src/Node/Entity/BlogEntryInterface.php index 1b9698fd..a216a2f6 100644 --- a/app/Drupal/niklan/src/Node/Entity/BlogEntryInterface.php +++ b/app/Drupal/niklan/src/Node/Entity/BlogEntryInterface.php @@ -4,9 +4,6 @@ namespace Drupal\niklan\Node\Entity; -/** - * @todo Remove - */ interface BlogEntryInterface extends NodeInterface { public function setExternalId(string $external_id): self; diff --git a/app/Drupal/niklan/src/Node/Entity/NodeInterface.php b/app/Drupal/niklan/src/Node/Entity/NodeInterface.php index 94eb0d7c..2ea7374b 100644 --- a/app/Drupal/niklan/src/Node/Entity/NodeInterface.php +++ b/app/Drupal/niklan/src/Node/Entity/NodeInterface.php @@ -6,9 +6,6 @@ use Drupal\node\NodeInterface as DrupalNodeInterface; -/** - * @todo Consider remove. - */ interface NodeInterface extends DrupalNodeInterface { } diff --git a/app/Drupal/niklan/src/Node/Entity/PortfolioInterface.php b/app/Drupal/niklan/src/Node/Entity/PortfolioInterface.php index 85f721ed..1649bb85 100644 --- a/app/Drupal/niklan/src/Node/Entity/PortfolioInterface.php +++ b/app/Drupal/niklan/src/Node/Entity/PortfolioInterface.php @@ -4,9 +4,6 @@ namespace Drupal\niklan\Node\Entity; -/** - * @todo Remove - */ interface PortfolioInterface extends NodeInterface { } diff --git a/app/Drupal/niklan/src/Plugin/Block/CopyrightBlock.php b/app/Drupal/niklan/src/Plugin/Block/CopyrightBlock.php deleted file mode 100644 index 5efc583a..00000000 --- a/app/Drupal/niklan/src/Plugin/Block/CopyrightBlock.php +++ /dev/null @@ -1,28 +0,0 @@ - 'niklan_copyright', - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Block/FollowLinksBlock.php b/app/Drupal/niklan/src/Plugin/Block/FollowLinksBlock.php deleted file mode 100644 index c1158f40..00000000 --- a/app/Drupal/niklan/src/Plugin/Block/FollowLinksBlock.php +++ /dev/null @@ -1,25 +0,0 @@ - 'niklan_follow', - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Block/MobileHeaderBarBlock.php b/app/Drupal/niklan/src/Plugin/Block/MobileHeaderBarBlock.php deleted file mode 100644 index 5b0b031c..00000000 --- a/app/Drupal/niklan/src/Plugin/Block/MobileHeaderBarBlock.php +++ /dev/null @@ -1,26 +0,0 @@ - 'niklan_mobile_header_bar', - '#logo' => \theme_get_setting('logo.url'), - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Block/SidebarSearchFormBlock.php b/app/Drupal/niklan/src/Plugin/Block/SidebarSearchFormBlock.php deleted file mode 100644 index a6cb8773..00000000 --- a/app/Drupal/niklan/src/Plugin/Block/SidebarSearchFormBlock.php +++ /dev/null @@ -1,25 +0,0 @@ - 'niklan_sidebar_search_form', - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Block/TocBlock.php b/app/Drupal/niklan/src/Plugin/Block/TocBlock.php deleted file mode 100644 index 828906e3..00000000 --- a/app/Drupal/niklan/src/Plugin/Block/TocBlock.php +++ /dev/null @@ -1,28 +0,0 @@ - '@TODO REMOVE', - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Comment/AuthorName.php b/app/Drupal/niklan/src/Plugin/ExtraField/Display/Comment/AuthorName.php deleted file mode 100644 index 9c1b49a2..00000000 --- a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Comment/AuthorName.php +++ /dev/null @@ -1,33 +0,0 @@ - $entity->getAuthorName(), - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/BlogPost/MetaInformation.php b/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/BlogPost/MetaInformation.php deleted file mode 100644 index c1ab2cf3..00000000 --- a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/BlogPost/MetaInformation.php +++ /dev/null @@ -1,85 +0,0 @@ -dateFormatter = $container->get('date.formatter'); - - return $instance; - } - - #[\Override] - public function view(ContentEntityInterface $entity): array { - \assert($entity instanceof NodeInterface); - - return [ - '#theme' => 'niklan_blog_meta', - '#created' => $this->getCreatedDate($entity), - '#comment_count' => $this->getCommentCount(), - '#comments_url' => $this->getCommentsUrl(), - '#estimated_read_time' => $this->getEstimatedReadTime(), - ]; - } - - protected function getCreatedDate(NodeInterface $node): string { - return $this->dateFormatter->format($node->getCreatedTime(), 'dmy'); - } - - protected function getCommentCount(): int { - $count = $this->getEntity()->get('comment_node_blog_entry')->first()?->get('comment_count')->getValue(); - \assert(\is_int($count) || \is_null($count)); - - return $count ?? 0; - } - - protected function getCommentsUrl(): Url { - return $this->getEntity()->toUrl('canonical', ['fragment' => 'comments']); - } - - protected function getEstimatedReadTime(): int { - $content = $this - ->getEntity() - ->get('external_content') - ->first() - ?->get('content') - ->getValue(); - - if (!$content instanceof ContentNodeInterface) { - return 0; - } - - $calculator = new EstimatedReadTimeCalculator(); - - return $calculator->calculate($content); - } - -} diff --git a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/PreviousNext.php b/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/PreviousNext.php deleted file mode 100644 index 73448fba..00000000 --- a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/PreviousNext.php +++ /dev/null @@ -1,34 +0,0 @@ - 'niklan_previous_next', - '#entity' => $entity, - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/Share.php b/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/Share.php deleted file mode 100644 index 843a82b3..00000000 --- a/app/Drupal/niklan/src/Plugin/ExtraField/Display/Node/Share.php +++ /dev/null @@ -1,38 +0,0 @@ - 'niklan_share', - '#url' => $entity - ->toUrl('canonical', ['absolute' => TRUE]) - ->toString(TRUE) - ->getGeneratedUrl(), - '#text' => $entity->label(), - ]; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatter.php b/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatter.php deleted file mode 100644 index 3032bfdd..00000000 --- a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatter.php +++ /dev/null @@ -1,89 +0,0 @@ -get(EntityTypeManagerInterface::class), - ); - } - - #[\Override] - public function viewElements(FieldItemListInterface $items, $langcode): array { - $element = []; - - foreach ($items as $item) { - \assert($item instanceof EntityReferenceItem); - - $media = $item->get('entity')->getValue(); - \assert($media instanceof MediaInterface); - - $file_id = $media->getSource()->getSourceFieldValue($media); - $file = $this->entityTypeManager->getStorage('file')->load($file_id); - \assert($file instanceof FileInterface); - - $element[] = [ - '#theme' => 'niklan_media_attached_file', - '#uri' => $file->getFileUri(), - '#filename' => $file->getFilename(), - '#filesize' => ByteSizeMarkup::create($file->getSize() ?? 0), - '#label' => $media->label(), - ]; - } - - return $element; - } - - #[\Override] - public static function isApplicable(FieldDefinitionInterface $field_definition): bool { - $target_type = $field_definition - ->getFieldStorageDefinition() - ->getSetting('target_type'); - - return $target_type === 'media'; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatter.php b/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatter.php deleted file mode 100644 index 3ab318e8..00000000 --- a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatter.php +++ /dev/null @@ -1,159 +0,0 @@ - new TranslatableMarkup('Content'), - 'media' => new TranslatableMarkup('Media item'), - ]; - $element['image_link']['#options'] = $link_types; - - return $element; - } - - #[\Override] - public function settingsSummary(): array { - $summary = parent::settingsSummary(); - - $link_types = [ - 'content' => new TranslatableMarkup('Linked to content'), - 'media' => new TranslatableMarkup('Linked to media item'), - ]; - // Display this setting only if image is linked. - $image_link_setting = $this->getSetting('image_link'); - - if (isset($link_types[$image_link_setting])) { - $summary[] = $link_types[$image_link_setting]; - } - - return $summary; - } - - #[\Override] - public function viewElements(FieldItemListInterface $items, $langcode): array { - \assert($items instanceof EntityReferenceFieldItemListInterface); - - $elements = []; - $media_items = $this->getEntitiesToView($items, $langcode); - - // Early opt-out if the field is empty. - if (!$media_items) { - return $elements; - } - - $responsive_image_style = $this->getSetting('responsive_image_style'); - - foreach ($media_items as $delta => $media) { - \assert($media instanceof MediaInterface); - - $cache_tags = []; - $cache_tags = Cache::mergeTags($cache_tags, $media->getCacheTags()); - $elements[$delta] = [ - '#theme' => 'responsive_image_formatter', - '#responsive_image_style_id' => $responsive_image_style ?? '', - '#item' => $media->get('thumbnail')->first(), - '#item_attributes' => [], - '#url' => $this->getMediaThumbnailUrl($media, $items->getEntity()), - '#cache' => [ - 'tags' => $cache_tags, - ], - ]; - } - - // Add cacheability of the image style setting. - if ($this->getSetting('image_link')) { - $image_style = $this - ->responsiveImageStyleStorage - ->load($responsive_image_style); - - if ($image_style) { - $cache_a = CacheableMetadata::createFromRenderArray($elements); - $cache_b = CacheableMetadata::createFromObject($image_style); - $cache_a->merge($cache_b)->applyTo($elements); - } - } - - return $elements; - } - - #[\Override] - public static function isApplicable(FieldDefinitionInterface $field_definition): bool { - // This formatter is only available for entity types that reference - // media items. - return $field_definition - ->getFieldStorageDefinition() - ->getSetting('target_type') === 'media'; - } - - /** - * {@inheritdoc} - * - * @param \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem<\Drupal\Core\Entity\EntityInterface> $item - * - * This has to be overridden because FileFormatterBase expects $item to be - * of type \Drupal\file\Plugin\Field\FieldType\FileItem and calls - * isDisplayed() which is not in FieldItemInterface. - */ - #[\Override] - protected function needsEntityLoad(EntityReferenceItem $item): bool { - return !$item->hasNewEntity(); - } - - /** - * Get the URL for the media thumbnail. - * - * @param \Drupal\media\MediaInterface $media - * The media item. - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity that the field belongs to. - * - * @throws \Drupal\Core\Entity\EntityMalformedException - */ - protected function getMediaThumbnailUrl(MediaInterface $media, EntityInterface $entity): ?Url { - $url = NULL; - $image_link_setting = $this->getSetting('image_link'); - - // Check if the formatter involves a link. - if ($image_link_setting === 'content') { - if (!$entity->isNew()) { - $url = $entity->toUrl(); - } - } - elseif ($image_link_setting === 'media') { - $url = $media->toUrl(); - } - - return $url; - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/OEmbedVideo.php b/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/OEmbedVideo.php deleted file mode 100644 index 6343d386..00000000 --- a/app/Drupal/niklan/src/Plugin/Field/FieldFormatter/OEmbedVideo.php +++ /dev/null @@ -1,175 +0,0 @@ -get(EntityTypeManagerInterface::class), - $container->get(LinkGeneratorInterface::class), - $container->get(AccountInterface::class), - ); - } - - /** - * {@inheritdoc} - */ - #[\Override] - public function settingsForm(array $form, FormStateInterface $form_state): array { - $element = parent::settingsForm($form, $form_state); - - $storage = $this->entityTypeManager->getStorage('responsive_image_style'); - $responsive_image_options = []; - - foreach ($storage->loadMultiple() as $machine_name => $responsive_image_style) { - \assert($responsive_image_style instanceof ResponsiveImageStyleInterface); - - if (!$responsive_image_style->hasImageStyleMappings()) { - continue; - } - - $responsive_image_options[$machine_name] = $responsive_image_style->label(); - } - - $element['responsive_image_style'] = [ - '#title' => new TranslatableMarkup('Responsive image style'), - '#type' => 'select', - '#default_value' => $this->getSetting('responsive_image_style') ?: NULL, - '#required' => TRUE, - '#options' => $responsive_image_options, - '#description' => [ - '#markup' => $this->linkGenerator->generate( - new TranslatableMarkup('Configure Responsive Image Styles'), - new Url('entity.responsive_image_style.collection'), - ), - '#access' => $this->currentUser->hasPermission( - 'administer responsive image styles', - ), - ], - ]; - - return $element; - } - - #[\Override] - public function settingsSummary(): array { - $summary = []; - - $storage = $this->entityTypeManager->getStorage('responsive_image_style'); - $responsive_image_style = $storage - ->load($this->getSetting('responsive_image_style')); - - if ($responsive_image_style) { - $summary[] = (string) new TranslatableMarkup( - // phpcs:disable Drupal.Semantics.FunctionT.NotLiteralString - string: 'Responsive image style: @responsive_image_style', - arguments: ['@responsive_image_style' => $responsive_image_style->label()], - ); - } - else { - $summary[] = (string) new TranslatableMarkup('Select a responsive image style.'); - } - - return $summary; - } - - #[\Override] - public function viewElements(FieldItemListInterface $items, $langcode): array { - $elements = []; - - foreach ($items as $delta => $item) { - $elements[$delta] = [ - '#type' => 'niklan_oembed_video', - '#media' => $item->getEntity(), - '#preview_responsive_image_style' => $this->getSetting( - 'responsive_image_style', - ), - ]; - } - - return $elements; - } - - #[\Override] - public static function isApplicable(FieldDefinitionInterface $field_definition): bool { - if ($field_definition->getTargetEntityTypeId() !== 'media') { - return FALSE; - } - - if (!$field_definition->getTargetBundle()) { - return FALSE; - } - - $media_type = MediaType::load($field_definition->getTargetBundle()); - - if (!$media_type instanceof MediaTypeInterface) { - return FALSE; - } - - // @phpstan-ignore-next-line - $is_video = $media_type->getSource()->getPluginDefinition()['id'] === 'video'; - $is_oembed = $media_type->getSource() instanceof OEmbedInterface; - - return $is_oembed && $is_video; - } - - /** - * {@inheritdoc} - */ - public static function defaultSettings(): array { - return [ - 'responsive_image_style' => '', - ] + parent::defaultSettings(); - } - -} diff --git a/app/Drupal/niklan/src/Plugin/Filter/PrismJsHighlighter.php b/app/Drupal/niklan/src/Plugin/Filter/PrismJsHighlighter.php deleted file mode 100644 index 973797bb..00000000 --- a/app/Drupal/niklan/src/Plugin/Filter/PrismJsHighlighter.php +++ /dev/null @@ -1,48 +0,0 @@ -` tag inside text and if founds it, attach - * library with syntax highlighter library. This way library will be attached - * on pages where text contains code. - * - * Filter used instead of simple preprocess because there are cases when - * preprocess wont work. F.e. library attached on paragraph type 'code', but - * content doesn't contains any of such paragraphs, so library wont be attached. - * But this material can has code to highlight inside comments. - * - * @deprecated Remove it after a new theme is deployed. - */ -#[Filter( - id: 'niklan_prismjs', - title: new TranslatableMarkup('Prism.js'), - type: FilterInterface::TYPE_MARKUP_LANGUAGE, - weight: 100, -)] -final class PrismJsHighlighter extends FilterBase { - - #[\Override] - public function process($text, $langcode): FilterProcessResult { - $result = new FilterProcessResult($text); - - if (!\stristr($text, 'addAttachments(['library' => ['niklan/code-highlight']]); - - return $result; - } - -} diff --git a/app/Drupal/niklan/src/Search/Controller/Search.php b/app/Drupal/niklan/src/Search/Controller/Search.php index 2d7f8287..cd8021c0 100644 --- a/app/Drupal/niklan/src/Search/Controller/Search.php +++ b/app/Drupal/niklan/src/Search/Controller/Search.php @@ -58,9 +58,9 @@ private function buildResults(?string $query): array { } private function buildSearchResult(EntitySearchResult $result): array { - $storage = $this->entityTypeManager->getStorage($result->getEntityTypeId()); - $view_builder = $this->entityTypeManager->getViewBuilder($result->getEntityTypeId()); - $entity = $storage->load($result->getEntityId()); + $storage = $this->entityTypeManager->getStorage($result->entityTypeId); + $view_builder = $this->entityTypeManager->getViewBuilder($result->entityTypeId); + $entity = $storage->load($result->entityId); return $entity ? $view_builder->view($entity, 'search_result') : []; } diff --git a/app/Drupal/niklan/src/Search/Data/EntitySearchResult.php b/app/Drupal/niklan/src/Search/Data/EntitySearchResult.php index acada2f6..45450141 100644 --- a/app/Drupal/niklan/src/Search/Data/EntitySearchResult.php +++ b/app/Drupal/niklan/src/Search/Data/EntitySearchResult.php @@ -4,27 +4,12 @@ namespace Drupal\niklan\Search\Data; -/** - * @todo Remove methods and make properties public readonly. - */ final class EntitySearchResult { public function __construct( - protected string $entityTypeId, - protected int|string $entityId, - protected string $language, + public string $entityTypeId, + public int|string $entityId, + public string $language, ) {} - public function getEntityTypeId(): string { - return $this->entityTypeId; - } - - public function getEntityId(): int|string { - return $this->entityId; - } - - public function getLanguage(): string { - return $this->language; - } - } diff --git a/app/Drupal/niklan/src/Search/Data/EntitySearchResults.php b/app/Drupal/niklan/src/Search/Data/EntitySearchResults.php index 234b1cae..6bb7b5c0 100644 --- a/app/Drupal/niklan/src/Search/Data/EntitySearchResults.php +++ b/app/Drupal/niklan/src/Search/Data/EntitySearchResults.php @@ -26,7 +26,8 @@ public function getEntityIds(): array { $result = []; foreach ($this->items as $item) { - $result[$item->getEntityTypeId()][] = $item->getEntityId(); + \assert($item instanceof EntitySearchResult); + $result[$item->entityTypeId][] = $item->entityId; } return $result; diff --git a/app/Drupal/niklan/src/Search/Repository/EntitySearch.php b/app/Drupal/niklan/src/Search/Repository/EntitySearch.php index 963a47d9..00a1a6a8 100644 --- a/app/Drupal/niklan/src/Search/Repository/EntitySearch.php +++ b/app/Drupal/niklan/src/Search/Repository/EntitySearch.php @@ -7,9 +7,6 @@ use Drupal\niklan\Search\Data\EntitySearchResults; use Drupal\niklan\Search\Data\SearchParams; -/** - * @todo Consider remove it. - */ interface EntitySearch { public function search(SearchParams $params): EntitySearchResults; diff --git a/app/Drupal/niklan/src/Tag/Repository/TagUsageStatistics.php b/app/Drupal/niklan/src/Tag/Repository/TagUsageStatistics.php index b75e206a..1bc52155 100644 --- a/app/Drupal/niklan/src/Tag/Repository/TagUsageStatistics.php +++ b/app/Drupal/niklan/src/Tag/Repository/TagUsageStatistics.php @@ -4,9 +4,6 @@ namespace Drupal\niklan\Tag\Repository; -/** - * @todo Remove it. - */ interface TagUsageStatistics { /** diff --git a/app/Drupal/niklan/src/Utils/MediaHelper.php b/app/Drupal/niklan/src/Utils/MediaHelper.php index bbd86d4e..e9dd2589 100644 --- a/app/Drupal/niklan/src/Utils/MediaHelper.php +++ b/app/Drupal/niklan/src/Utils/MediaHelper.php @@ -12,10 +12,7 @@ public static function getFileFromMediaField(FieldableEntityInterface $entity, string $field_name): ?FileInterface { $media = $entity->get($field_name)->first()?->get('entity')->getValue(); - - if (!$media instanceof MediaInterface) { - return NULL; - } + \assert(\is_null($media) || $media instanceof MediaInterface); return self::getFile($media); } diff --git a/app/Drupal/niklan/templates/niklan-blog-meta.html.twig b/app/Drupal/niklan/templates/niklan-blog-meta.html.twig deleted file mode 100644 index 2a524f49..00000000 --- a/app/Drupal/niklan/templates/niklan-blog-meta.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present blog meta information. - * - * Available variables: - * - attributes: An attributes. - * - created: The formatted date when blog entry was created. - * - comment_count: The amount of comments. - * - comments_url: The anchor URL to comments. - * - estimated_read_time: The number of minutes estimated to read the article. - */ -#} -{% set count = comment_count %} -{% set comment_link_label %} - {%- trans -%} - {{ count }} comment - {%- plural count -%} - {{ count }} comments - {%- endtrans -%} -{% endset %} - -
{{ created }}
- {{- comment_link_label -}} -
{{ estimated_read_time }} {{ 'min.'|t }}
- diff --git a/app/Drupal/niklan/templates/niklan-copyright.html.twig b/app/Drupal/niklan/templates/niklan-copyright.html.twig deleted file mode 100644 index 6de1a2c4..00000000 --- a/app/Drupal/niklan/templates/niklan-copyright.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display copyrights. - * - * Available variables: - * - attributes: The main wrapper element attributes. - */ -#} - - {% set license_url = 'https://creativecommons.org/licenses/by-sa/4.0/legalcode.ru' %} - {% trans %}The content is published under Creative - Commons Attribution CC-BY-SA 4.0 license.{% endtrans %} - - © {{ 'now'|date('Y') }} Niklan - diff --git a/app/Drupal/niklan/templates/niklan-follow.html.twig b/app/Drupal/niklan/templates/niklan-follow.html.twig deleted file mode 100644 index 8b798244..00000000 --- a/app/Drupal/niklan/templates/niklan-follow.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display social links. - * - * Available variables: - * - attributes: The main wrapper element attributes. - */ -#} -{{ attach_library('niklan/follow') }} -{% set links = { - 'rss': 'https://niklan.net/blog.xml', - 'telegram': 'https://t.me/niklannet', - 'youtube': 'https://youtube.com/c/NiklanNet', - 'support': url('niklan.support'), -} %} - - - diff --git a/app/Drupal/niklan/templates/niklan-form-success.html.twig b/app/Drupal/niklan/templates/niklan-form-success.html.twig deleted file mode 100644 index d33d9d10..00000000 --- a/app/Drupal/niklan/templates/niklan-form-success.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display successful form submission. - * - * Available variables: - * - attributes: The main wrapper element attributes. - * - title: The message title. - * - message: The message body. - */ -#} - - - - - -
{{ title }}
-
-

{{ message }}

-
- diff --git a/app/Drupal/niklan/templates/niklan-last-content.html.twig b/app/Drupal/niklan/templates/niklan-last-content.html.twig deleted file mode 100644 index c039b7cd..00000000 --- a/app/Drupal/niklan/templates/niklan-last-content.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present last blog posts. - * - * Available variables: - * - attributes: An attributes. - * - items: An array with items to show. - * - title: A title for section. - * - more_url: (optional) An Url for 'more' of content. - * - more_label: (optional) A label for 'more_url'. - */ -#} - -

{{- title -}}

-
- {% for item in items %} -
- {{- item -}} -
- {% endfor %} -
- - {% if more_url and more_label %} - - {% endif %} - diff --git a/app/Drupal/niklan/templates/niklan-media-attached-file.html.twig b/app/Drupal/niklan/templates/niklan-media-attached-file.html.twig deleted file mode 100644 index f0ca861d..00000000 --- a/app/Drupal/niklan/templates/niklan-media-attached-file.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present attached media file. - * - * Available variables: - * - uri: The attached file URI. - * - filename: The filename. - * - filesize: The formatted filesize. - * - label: The files media name. - */ -#} - - {{- label -}} - — {{ filename -}}, - {{- filesize -}} - diff --git a/app/Drupal/niklan/templates/niklan-mobile-header-bar.html.twig b/app/Drupal/niklan/templates/niklan-mobile-header-bar.html.twig deleted file mode 100644 index 65f17144..00000000 --- a/app/Drupal/niklan/templates/niklan-mobile-header-bar.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display mobile header bar. - * - * Available variables: - * - attributes: The main wrapper element attributes. - * - logo: The site logo URL. - */ -#} -
-
- - Niklan -
-
-
diff --git a/app/Drupal/niklan/templates/niklan-oembed-video.html.twig b/app/Drupal/niklan/templates/niklan-oembed-video.html.twig deleted file mode 100644 index e4fd107b..00000000 --- a/app/Drupal/niklan/templates/niklan-oembed-video.html.twig +++ /dev/null @@ -1,23 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present optimized oEmbed video. - * - * Available variables: - * - attributes: HTML attributes for containing element. - * - preview: The contents used for thumbnail preview. - * - content: The content to be displayed. - */ -#} -{{ attach_library('niklan/oembed-video') }} - -
- {{- preview -}} -
- - diff --git a/app/Drupal/niklan/templates/niklan-share.html.twig b/app/Drupal/niklan/templates/niklan-share.html.twig deleted file mode 100644 index 0e4ac744..00000000 --- a/app/Drupal/niklan/templates/niklan-share.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display links with share URLs. - * - * Available variables: - * - attributes: The main wrapper element attributes. - * - url: The URL to share. - * - text: The title of shared content. - */ -#} -{{ attach_library('niklan/share') }} -{% set links = { - 'telegram': 'https://telegram.me/share/url?url=' ~ url ~ '&text=' ~ text, - 'twitter': 'https://twitter.com/intent/tweet?url=' ~ url ~ '&text=' ~ text, - 'vk': 'https://vk.com/share.php?url=' ~ url ~ '&title=' ~ text, - 'facebook': 'https://facebook.com/sharer/sharer.php?u=' ~ url, - 'mail': 'mailto:?subject=' ~ text ~ '&body=' ~ url, -} %} - - - - diff --git a/app/Drupal/niklan/templates/niklan-sidebar-search-form.html.twig b/app/Drupal/niklan/templates/niklan-sidebar-search-form.html.twig deleted file mode 100644 index c50fafee..00000000 --- a/app/Drupal/niklan/templates/niklan-sidebar-search-form.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{# -/** - * @file - * Default theme implementation to display sidebar search form. - * - * Available variables: - * - attributes: The main wrapper element attributes. - * - * @ingroup themeable - */ -#} -{% do attributes.setAttribute('action', path('niklan.search_page')) %} - - - - diff --git a/app/Drupal/niklan/templates/niklan-toc.html.twig b/app/Drupal/niklan/templates/niklan-toc.html.twig deleted file mode 100644 index db95baa7..00000000 --- a/app/Drupal/niklan/templates/niklan-toc.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present content TOC. - * - * Available variables: - * - attributes: The main wrapper element attributes. - * - links: The array with link for TOC. - */ -#} -{% import _self as toc %} -{% set bem_block = 'toc' %} - - {% set bem_base = bem_block ~ '__' %} - {% do attributes.removeClass(bem_block) %} - {{ toc.links(links, attributes, 0, bem_base) }} - - -{% macro links(links, attributes, toc_level, bem_base) %} - {% import _self as toc %} - {% if links %} - {% if toc_level == 0 %} - - {% for item in links %} -
  • - {{ item.text }} - {% if item.children %} - {{ toc.links(item.children, attributes, item.indent, bem_base) }} - {% endif %} -
  • - {% endfor %} - - {% else %} -
      - {% for item in links %} -
    • - {{ item.text }} - {% if item.children %} - {{ toc.links(item.children, attributes, item.indent + 1, bem_base) }} - {% endif %} -
    • - {% endfor %} -
    - {% endif %} - {% endif %} -{% endmacro %} diff --git a/app/Drupal/niklan/tests/src/Functional/Plugin/Filter/PrismJsHighlighterTest.php b/app/Drupal/niklan/tests/src/Functional/Plugin/Filter/PrismJsHighlighterTest.php deleted file mode 100644 index 9915f15b..00000000 --- a/app/Drupal/niklan/tests/src/Functional/Plugin/Filter/PrismJsHighlighterTest.php +++ /dev/null @@ -1,41 +0,0 @@ -filterManager->createInstance('niklan_prismjs'); - \assert($filter instanceof FilterInterface); - $expected_library = 'niklan/code-highlight'; - - $text = '**strong**'; - $result = $filter->process( - $text, - LanguageInterface::LANGCODE_NOT_SPECIFIED, - ); - self::assertArrayNotHasKey('library', $result->getAttachments()); - - $text = '
    '; - $result = $filter->process( - $text, - LanguageInterface::LANGCODE_NOT_SPECIFIED, - ); - self::assertContains( - $expected_library, - $result->getAttachments()['library'], - ); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/BlockTestBase.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/BlockTestBase.php deleted file mode 100644 index 4249b4d5..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/BlockTestBase.php +++ /dev/null @@ -1,27 +0,0 @@ -blockManager = $this->container->get('plugin.manager.block'); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/CopyrightBlockTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/CopyrightBlockTest.php deleted file mode 100644 index 37f4f7ce..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/CopyrightBlockTest.php +++ /dev/null @@ -1,30 +0,0 @@ -blockManager->createInstance('niklan_copyright'); - \assert($block_instance instanceof BlockPluginInterface); - $build = $block_instance->build(); - $this->render($build); - - self::assertRaw('CC-BY-SA 4.0'); - self::assertRaw('©'); - self::assertRaw('Niklan'); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/FollowLinksBlockTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/FollowLinksBlockTest.php deleted file mode 100644 index d00e54ad..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/FollowLinksBlockTest.php +++ /dev/null @@ -1,34 +0,0 @@ -blockManager - ->createInstance('niklan_follow_links'); - \assert($block_instance instanceof BlockPluginInterface); - $build = $block_instance->build(); - $this->render($build); - - self::assertRaw('https://niklan.net/blog.xml'); - self::assertRaw('https://t.me/niklannet'); - self::assertRaw('https://youtube.com/c/NiklanNet'); - self::assertRaw(Url::fromRoute('niklan.support')->getInternalPath()); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/MobileHeaderBarBlockTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/MobileHeaderBarBlockTest.php deleted file mode 100644 index 527efbb5..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/MobileHeaderBarBlockTest.php +++ /dev/null @@ -1,33 +0,0 @@ -blockManager - ->createInstance('niklan_mobile_header_bar'); - \assert($block_instance instanceof BlockPluginInterface); - $build = $block_instance->build(); - $this->render($build); - - self::assertRaw('Site logo'); - self::assertRaw(Url::fromRoute('')->setAbsolute()->toString()); - self::assertCount(1, $this->cssSelect('.js-navigation-mobile-toggle')); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/SidebarSearchFormBlockTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/SidebarSearchFormBlockTest.php deleted file mode 100644 index f22db41a..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Block/SidebarSearchFormBlockTest.php +++ /dev/null @@ -1,34 +0,0 @@ -blockManager - ->createInstance('niklan_node_sidebar_search_form'); - \assert($block instanceof SidebarSearchFormBlock); - $build = $block->build(); - $this->render($build); - - $search_action_url = Url::fromRoute('niklan.search_page')->toString(); - self::assertRaw($search_action_url); - self::assertCount(1, $this->cssSelect('.sidebar-search-form input')); - self::assertCount(1, $this->cssSelect('.sidebar-search-form button')); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Comment/AuthorNameTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Comment/AuthorNameTest.php deleted file mode 100644 index 60ea7ea2..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Comment/AuthorNameTest.php +++ /dev/null @@ -1,63 +0,0 @@ -createExtraFieldDisplayInstance('author_name'); - $build = $plugin->view($this->comment); - $this->render($build); - - self::assertRaw($this->author->getAccountName()); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - $this->installEntitySchema('user'); - $this->installEntitySchema('comment'); - - $this->author = $this->createUser(); - - CommentType::create([ - 'id' => 'test', - ]); - - $this->comment = Comment::create([ - 'comment_type' => 'test', - 'uid' => $this->author->id(), - ]); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/BlogPost/MetaInformationTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/BlogPost/MetaInformationTest.php deleted file mode 100644 index dffe60bf..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/BlogPost/MetaInformationTest.php +++ /dev/null @@ -1,75 +0,0 @@ -prophesize(FieldItemListInterface::class); - - $comment_count = $this->prophesize(TypedDataInterface::class); - $comment_count->getValue()->willReturn(7); - - $comment_node_blog_entry_0 = $this->prophesize(CommentItem::class); - $comment_node_blog_entry_0 - ->get('comment_count') - ->willReturn($comment_count->reveal()); - - $comment_node_blog_entry_list = $this - ->prophesize(FieldItemListInterface::class); - $comment_node_blog_entry_list - ->first() - ->willReturn($comment_node_blog_entry_0->reveal()); - - $comments_url = Url::fromRoute('entity.node.canonical', ['node' => 1]); - - $node = $this->prophesize(NodeInterface::class); - $node->getCreatedTime()->willReturn(123_456_789); - $node - ->get('comment_node_blog_entry') - ->willReturn($comment_node_blog_entry_list->reveal()); - $node->toUrl(Argument::cetera())->willReturn($comments_url); - $node->get('external_content')->willReturn($external_content->reveal()); - - $plugin = $this->createExtraFieldDisplayInstance('meta_information'); - $plugin->setEntity($node->reveal()); - $build = $plugin->view($node->reveal()); - $this->render($build); - - self::assertCount(1, $this->cssSelect('.blog-meta')); - self::assertRaw('0 min.'); - self::assertRaw('11/30/1973'); - self::assertRaw('7 comments'); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - DateFormat::create([ - 'id' => 'fallback', - 'pattern' => 'D, m/d/Y - H:i', - ])->save(); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/PreviousNextTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/PreviousNextTest.php deleted file mode 100644 index 850bdfa6..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/PreviousNextTest.php +++ /dev/null @@ -1,44 +0,0 @@ -createBlogEntry(['title' => 'Node A', 'created' => 1])->save(); - $this->createBlogEntry(['title' => 'Node B', 'created' => 2])->save(); - $this->createBlogEntry(['title' => 'Node C', 'created' => 3])->save(); - - $plugin = $this->createExtraFieldDisplayInstance('previous_next'); - // Node B as a reference. - $build = $plugin->view(Node::load(2)); - $this->render($build); - - self::assertRaw('Node A'); - self::assertRaw('Node C'); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - $this->setUpBlogEntry(); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/ShareTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/ShareTest.php deleted file mode 100644 index 51d671a3..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/Display/Node/ShareTest.php +++ /dev/null @@ -1,46 +0,0 @@ -createBlogEntry(['title' => 'Node A'])->save(); - - $plugin = $this->createExtraFieldDisplayInstance('share'); - $build = $plugin->view(Node::load(1)); - $this->render($build); - - self::assertCount(1, $this->cssSelect('.share')); - self::assertRaw('node/1'); - self::assertRaw('telegram.me'); - self::assertRaw('twitter.com'); - self::assertRaw('vk.com'); - self::assertRaw('facebook.com'); - self::assertRaw('mailto:?subject'); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - $this->setUpBlogEntry(); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/ExtraFieldTestBase.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/ExtraFieldTestBase.php deleted file mode 100644 index 35162854..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/ExtraField/ExtraFieldTestBase.php +++ /dev/null @@ -1,48 +0,0 @@ -extraFieldDisplayManager = $this - ->container - ->get('plugin.manager.extra_field_display'); - } - - /** - * Creates an instance for extra field display. - * - * @param string $plugin_id - * The plugin ID. - * @param array $configuration - * The plugin configuration. - */ - protected function createExtraFieldDisplayInstance(string $plugin_id, array $configuration = []): ExtraFieldDisplayInterface { - return $this - ->extraFieldDisplayManager - ->createInstance($plugin_id, $configuration); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatterTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatterTest.php deleted file mode 100644 index f88e8d6f..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaAttachedFilesFormatterTest.php +++ /dev/null @@ -1,103 +0,0 @@ -container - ->get('entity_display.repository') - ->getViewDisplay('node', 'blog_entry', 'default') - ->setComponent('field_media_reference', [ - 'type' => 'niklan_attached_files', - ]) - ->save(); - - $file = File::create([ - 'uri' => \current($this->getTestFiles('text'))->uri, - ]); - self::assertEquals(\SAVED_NEW, $file->save()); - - $media_image = Media::create([ - 'bundle' => 'file', - 'name' => 'Test file', - 'field_media_file' => $file->id(), - ]); - self::assertEquals(\SAVED_NEW, $media_image->save()); - - $node = Node::create([ - 'type' => 'blog_entry', - 'title' => $this->randomMachineName(), - 'field_media_reference' => [ - ['target_id' => $media_image->id()], - ], - ]); - self::assertEquals(\SAVED_NEW, $node->save()); - - $build = $this - ->container - ->get('entity_type.manager') - ->getViewBuilder('node') - ->view($node, 'default'); - $this->render($build); - - self::assertCount(1, $this->cssSelect('a.attached-file')); - self::assertCount(1, $this->cssSelect('.attached-file__filename')); - self::assertRaw($media_image->label()); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - $this->installEntitySchema('file'); - $this->installSchema('file', ['file_usage']); - $this->installEntitySchema('media'); - $this->createMediaType('file', ['id' => 'file']); - $blog_type = $this->setUpBlogEntry(); - - $field_storage = FieldStorageConfig::create([ - 'field_name' => 'field_media_reference', - 'type' => 'entity_reference', - 'entity_type' => 'node', - 'cardinality' => 1, - 'settings' => [ - 'target_type' => 'media', - ], - ]); - $field_storage->save(); - - FieldConfig::create([ - 'field_storage' => $field_storage, - 'bundle' => $blog_type->id(), - 'label' => 'Reference media', - 'translatable' => FALSE, - ])->save(); - } - -} diff --git a/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatterTest.php b/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatterTest.php deleted file mode 100644 index b44c4da3..00000000 --- a/app/Drupal/niklan/tests/src/Kernel/Plugin/Field/FieldFormatter/MediaResponsiveThumbnailFormatterTest.php +++ /dev/null @@ -1,269 +0,0 @@ -setFormatterSettings([ - 'responsive_image_style' => 'fallback', - 'image_link' => 'content', - ]); - - $node = Node::create([ - 'type' => 'blog_entry', - 'title' => $this->randomMachineName(), - ]); - self::assertEquals(\SAVED_NEW, $node->save()); - $this->renderNode($node); - - self::assertCount(0, $this->cssSelect('article picture')); - } - - /** - * Tests that formatter works with link to a content. - */ - public function testFormatterLinkedToContent(): void { - $this->setFormatterSettings([ - 'responsive_image_style' => 'fallback', - 'image_link' => 'content', - ]); - - $file = File::create([ - 'uri' => \current($this->getTestFiles('image'))->uri, - ]); - self::assertEquals(\SAVED_NEW, $file->save()); - - $media_image = Media::create([ - 'bundle' => 'image', - 'name' => 'Test image', - 'field_media_image' => $file->id(), - ]); - self::assertEquals(\SAVED_NEW, $media_image->save()); - - $node = Node::create([ - 'type' => 'blog_entry', - 'title' => $this->randomMachineName(), - 'field_media_reference' => $media_image, - ]); - self::assertEquals(\SAVED_NEW, $node->save()); - - $this->renderNode($node); - - self::assertCount(1, $this->cssSelect('article picture img')); - self::assertCount(1, $this->cssSelect("article a[href='/node/{$node->id()}'] picture")); - self::assertRaw($file->getFilename()); - } - - /** - * Tests that formatter works with link to a media. - */ - public function testFormatterLinkedToMedia(): void { - $this->setFormatterSettings([ - 'responsive_image_style' => 'fallback', - 'image_link' => 'media', - ]); - - $file = File::create([ - 'uri' => \current($this->getTestFiles('image'))->uri, - ]); - self::assertEquals(\SAVED_NEW, $file->save()); - - $media_image = Media::create([ - 'bundle' => 'image', - 'name' => 'Test image', - 'field_media_image' => $file->id(), - ]); - self::assertEquals(\SAVED_NEW, $media_image->save()); - - $node = Node::create([ - 'type' => 'blog_entry', - 'title' => $this->randomMachineName(), - 'field_media_reference' => $media_image, - ]); - self::assertEquals(\SAVED_NEW, $node->save()); - - $this->renderNode($node); - - self::assertCount(1, $this->cssSelect('article picture img')); - // By default, canonical link is directing on edit form. - self::assertCount(1, $this->cssSelect("article a[href='/media/{$media_image->id()}/edit'] picture")); - self::assertRaw($file->getFilename()); - } - - /** - * Tests that settings form allows to set up all expected settings. - */ - public function testSettingsForm(): void { - $formatter = $this->getFormatterInstance(); - $plugin_form = $formatter->settingsForm([], new FormState()); - - self::assertArrayHasKey('image_link', $plugin_form); - self::assertArrayHasKey('responsive_image_style', $plugin_form); - } - - /** - * Tests that settings summary contains all expected summary. - * - * @param string|null $setting_name - * The setting name. - * @param string|null $setting_value - * The settings value. - * @param string $expected_summary - * The expected summary. - * - * @dataProvider settingsSummaryDataProvider - */ - public function testSettingsSummary(?string $setting_name, ?string $setting_value, string $expected_summary): void { - $formatter = $this->getFormatterInstance(); - - if ($setting_value) { - $formatter->setSetting($setting_name, $setting_value); - } - - $summary = $formatter->settingsSummary(); - - // They are most likely is translatable strings. - foreach ($summary as $delta => $value) { - $summary[$delta] = (string) $value; - } - - self::assertContains($expected_summary, $summary); - } - - /** - * Provides settings summary data for testing. - */ - public function settingsSummaryDataProvider(): \Generator { - yield [NULL, NULL, 'Select a responsive image style.']; - yield ['image_link', 'content', 'Linked to content']; - yield ['image_link', 'media', 'Linked to media item']; - yield [ - 'responsive_image_style', - 'fallback', - 'Responsive image style: Fallback', - ]; - } - - /** - * Updates formatter settings for tested field. - * - * @param array $settings - * The formatter settings. - */ - protected function setFormatterSettings(array $settings): void { - $this - ->container - ->get('entity_display.repository') - ->getViewDisplay('node', 'blog_entry', 'default') - ->setComponent('field_media_reference', [ - 'type' => 'niklan_responsive_media_thumbnail', - 'settings' => $settings, - ]) - ->save(); - } - - /** - * Renders a node in default view mode. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ - protected function renderNode(NodeInterface $node): void { - $build = $this - ->container - ->get('entity_type.manager') - ->getViewBuilder('node') - ->view($node, 'default'); - $this->render($build); - } - - /** - * Gets formatter instance. - */ - protected function getFormatterInstance(): MediaResponsiveThumbnailFormatter { - $field_definitions = $this - ->container - ->get('entity_field.manager') - ->getFieldDefinitions('node', 'blog_entry'); - - return $this - ->container - ->get('plugin.manager.field.formatter') - ->getInstance([ - 'configuration' => [ - 'type' => 'niklan_responsive_media_thumbnail', - ], - 'view_mode' => 'full', - 'field_definition' => $field_definitions['field_media_reference'], - ]); - } - - #[\Override] - protected function setUp(): void { - parent::setUp(); - - $this->installEntitySchema('file'); - $this->installSchema('file', ['file_usage']); - $this->installEntitySchema('media'); - $this->createMediaType('image', ['id' => 'image']); - $blog_type = $this->setUpBlogEntry(); - - $field_storage = FieldStorageConfig::create([ - 'field_name' => 'field_media_reference', - 'type' => 'entity_reference', - 'entity_type' => 'node', - 'cardinality' => 1, - 'settings' => [ - 'target_type' => 'media', - ], - ]); - $field_storage->save(); - - FieldConfig::create([ - 'field_storage' => $field_storage, - 'bundle' => $blog_type->id(), - 'label' => 'Reference media', - 'translatable' => FALSE, - ])->save(); - - $style = ResponsiveImageStyle::create([ - 'id' => 'fallback', - 'label' => 'Fallback', - ]); - $style->addImageStyleMapping('test_breakpoint', '1x', [ - 'image_mapping_type' => 'image_style', - 'image_mapping' => 'small', - ]); - $style->save(); - } - -} diff --git a/app/Drupal/niklan/tests/src/Unit/Data/EntitySearchResultTest.php b/app/Drupal/niklan/tests/src/Unit/Data/EntitySearchResultTest.php index 32e884f8..faebc52c 100644 --- a/app/Drupal/niklan/tests/src/Unit/Data/EntitySearchResultTest.php +++ b/app/Drupal/niklan/tests/src/Unit/Data/EntitySearchResultTest.php @@ -29,9 +29,9 @@ final class EntitySearchResultTest extends UnitTestCase { public function testObject(string $entity_type_id, int|string $entity_id, string $language): void { $item = new EntitySearchResult($entity_type_id, $entity_id, $language); - self::assertEquals($entity_type_id, $item->getEntityTypeId()); - self::assertEquals($entity_id, $item->getEntityId()); - self::assertEquals($language, $item->getLanguage()); + self::assertEquals($entity_type_id, $item->entityTypeId); + self::assertEquals($entity_id, $item->entityId); + self::assertEquals($language, $item->language); } /** diff --git a/app/Drupal/niklan_installer/niklan_installer.info.yml b/app/Drupal/niklan_installer/niklan_installer.info.yml index 951983dc..70e5cfc5 100644 --- a/app/Drupal/niklan_installer/niklan_installer.info.yml +++ b/app/Drupal/niklan_installer/niklan_installer.info.yml @@ -1,3 +1,4 @@ +# Deprecated, remove after release following 24.12.3 name: Niklan Installer type: profile core_version_requirement: ^9 || ^10 diff --git a/composer.lock b/composer.lock index 82020d37..2ac44e55 100644 --- a/composer.lock +++ b/composer.lock @@ -4883,13 +4883,18 @@ "dist": { "type": "path", "url": "app/Drupal/laszlo", - "reference": "47c578d90087fbb7bb021243ee4662094b01b079" + "reference": "f248b5dd1dfe695f1050570fe06d54bfab76f716" }, "require": { "niklan-asset/lora": "^35", "niklan/niklan": "^1.0@dev" }, "type": "drupal-custom-theme", + "autoload": { + "psr-4": { + "Drupal\\laszlo\\": "src" + } + }, "transport-options": { "relative": true } diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index ace654e2..ee3cfb55 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -14,7 +14,6 @@ module: dynamic_page_cache: 0 editor: 0 external_content: 0 - extra_field: 0 field: 0 file: 0 file_mdm: 0 diff --git a/config/sync/filter.format.comments.yml b/config/sync/filter.format.comments.yml index e6414ba0..6166e58c 100644 --- a/config/sync/filter.format.comments.yml +++ b/config/sync/filter.format.comments.yml @@ -95,9 +95,3 @@ filters: status: true weight: -50 settings: { } - niklan_prismjs: - id: niklan_prismjs - provider: niklan - status: false - weight: -37 - settings: { }