Skip to content
Code-Schnipsel Gruppen Projekte
  • Henning Leutz's avatar
    78d9b1e2
    fix(phpstan): enhance code readability and adopt safer practices · 78d9b1e2
    verfasst von Henning Leutz
    Several changes have been made across multiple files to enhance code readability and follow safer
    coding practices.
    
    1. Breakdown of long lines of attributes/code into multiple lines with added comments for better
    readability. This was done in Submenu.php
    
    2. Replaced '==' operation with 'empty()' function to check for empty strings in Submenu.php
    
    3. Safer checking of if method 'getCachePath' exists on 'getSite' to avoid potential errors &
    Ensure the last insert ID is always an integer in the database PDO in DropDownMenu.php and
    Factory.php
    
    4. Refactor conditions for more clear type hinting in multiple files; including
    Independent/Handler.php, Independent/Items/AbstractMenuItem.php, Independent/Items/Site.php,
    Independent/Menu.php, MegaMenu.php, and NavTabs.php
    
    The concept of safe concatenation or use of '|null|' has been introduced where needed across many
    files.
    
    Related: #38
    78d9b1e2
    Verlauf
    fix(phpstan): enhance code readability and adopt safer practices
    verfasst von Henning Leutz
    Several changes have been made across multiple files to enhance code readability and follow safer
    coding practices.
    
    1. Breakdown of long lines of attributes/code into multiple lines with added comments for better
    readability. This was done in Submenu.php
    
    2. Replaced '==' operation with 'empty()' function to check for empty strings in Submenu.php
    
    3. Safer checking of if method 'getCachePath' exists on 'getSite' to avoid potential errors &
    Ensure the last insert ID is always an integer in the database PDO in DropDownMenu.php and
    Factory.php
    
    4. Refactor conditions for more clear type hinting in multiple files; including
    Independent/Handler.php, Independent/Items/AbstractMenuItem.php, Independent/Items/Site.php,
    Independent/Menu.php, MegaMenu.php, and NavTabs.php
    
    The concept of safe concatenation or use of '|null|' has been introduced where needed across many
    files.
    
    Related: #38
AbstractMenuItem.php 7,25 KiB
<?php

namespace QUI\Menu\Independent\Items;

use QUI;
use QUI\Locale;

use function array_filter;
use function is_array;
use function is_string;
use function json_decode;

/**
 * Base class for menu items
 */
abstract class AbstractMenuItem
{
    protected array $attributes = [];
    protected array $children = [];

    /**
     * @param array $attributes
     */
    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }

    //region frontend methods

    /**
     * @param ?Locale $Locale
     * @return string
     */
    public function getTitle(null | Locale $Locale = null): string
    {
        if ($Locale === null) {
            $Locale = QUI::getLocale();
        }

        $current = $Locale->getCurrent();
        $title = $this->attributes['title'];

        if (is_string($title)) {
            $title = json_decode($title, true);
        }

        if (isset($title[$current])) {
            return $title[$current];
        }

        return '';
    }

    /**
     * @param ?Locale $Locale
     * @return string
     */
    public function getShort(null | Locale $Locale = null): string
    {
        if ($Locale === null) {
            $Locale = QUI::getLocale();
        }

        $current = $Locale->getCurrent();
        $data = $this->getCustomData();

        if (!is_array($data) || !isset($data['short'])) {
            return '';
        }

        $short = $data['short'];

        if (is_string($short)) {
            $short = json_decode($short, true);
        }

        if (isset($short[$current])) {
            return $short[$current];
        }

        return '';
    }

    /**
     * @param Locale|null $Locale
     * @return string
     */
    public function getName(null | Locale $Locale = null): string
    {
        if ($Locale === null) {
            $Locale = QUI::getLocale();
        }

        $data = $this->getCustomData();
        $current = $Locale->getCurrent();

        if (is_array($data) && isset($data['name'])) {
            if (is_string($data['name'])) {
                $name = json_decode($data['name'], true);
            } else {
                $name = $data['name'];
            }

            if (isset($name[$current])) {
                return $name[$current];
            }
        }

        return $this->getTitle($Locale);
    }

    /**
     * alias for name
     * - can be used for the `a title=""` attribute
     *
     * @param Locale|null $Locale
     * @return string
     */
    public function getTitleAttribute(null | Locale $Locale = null): string
    {
        return $this->getName($Locale);
    }

    /**
     * @return string
     */
    public function getUrl(): string
    {
        return '';
    }

    /**
     * @return string
     */
    public function getIcon(): string
    {
        if (isset($this->attributes['icon'])) {
            return $this->attributes['icon'];
        }

        return '';
    }

    /**
     * @return string
     */
    public function getIdentifier(): string
    {
        if (isset($this->attributes['identifier'])) {
            return $this->attributes['identifier'];
        }

        return '';
    }

    /**
     * @return string
     */
    public function getRel(): string
    {
        $data = $this->getCustomData();

        if (is_array($data) && isset($data['rel'])) {
            return $data['rel'];
        }

        return '';
    }

    /**
     * @return string
     */
    public function getTarget(): string
    {
        $data = $this->getCustomData();

        if (is_array($data) && isset($data['target'])) {
            switch ($data['target']) {
                case "_self":
                case "frame":
                case "popup":
                case "_blank":
                case "_top":
                case "_parent":
                    return $data['target'];
            }
        }

        return '';
    }

    /**
     * return the menu typ for the children
     *
     * @return string
     */
    public function getMenuType(): string
    {
        $data = $this->getCustomData();

        if (is_array($data) && isset($data['menuType'])) {
            return $data['menuType'];
        }

        return '';
    }

    /**
     * @return mixed
     */
    public function getCustomData(): mixed
    {
        if (isset($this->attributes['data'])) {
            return $this->attributes['data'];
        }

        return null;
    }

    /**
     * @param Locale|null $Locale
     * @return string
     */
    public function getHTML(null | Locale $Locale = null): string
    {
        if ($Locale === null) {
            $Locale = QUI::getLocale();
        }

        $url = $this->getUrl();
        $title = $this->getTitle($Locale);
        $name = $this->getName($Locale);
        $relValue = $this->getRel();

        // rel attribute
        $rel = '';

        if (!empty($relValue)) {
            switch ($relValue) {
                case 'alternate':
                case 'author':
                case 'bookmark':
                case 'external':
                case 'help':
                case 'license':
                case 'next':
                case 'nofollow':
                case 'noopener':
                case 'noreferrer':
                case 'prev':
                case 'search':
                case 'tag':
                    $rel = 'rel="' . $relValue . '"';
                    break;
            }
        }

        // target attribute
        $target = $this->getTarget();
        $targetAttribute = '';

        if (!empty($target)) {
            $targetAttribute = $target;
        }

        // html link
        return "<a href=\"$url\" title=\"$title\" $rel $targetAttribute>$name</a>";
    }

    //endregion

    //region status

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->getStatus();
    }

    /**
     * @return bool
     */
    public function getStatus(): bool
    {
        $data = $this->getCustomData();

        if (is_array($data) && isset($data['status'])) {
            return !!$data['status'];
        }

        return true;
    }

    //endregion

    //region type stuff

    abstract public static function itemTitle();

    /**
     * Short description of the menu types
     *
     * @return string
     */
    public static function itemShort(): string
    {
        return '';
    }

    /**
     * @return string
     */
    public static function itemIcon(): string
    {
        return 'fa fa-file-o';
    }

    /**
     * @return string
     */
    public static function itemJsControl(): string
    {
        return '';
    }

    //endregion

    //region children

    /**
     * Return the children of this item
     *
     * @param bool $onlyActive - if true, returns only the active children, if false, all children are returned
     * @return AbstractMenuItem[]
     */
    public function getChildren(bool $onlyActive = true): array
    {
        if ($onlyActive === false) {
            return $this->children;
        }

        return array_filter($this->children, function ($Item) {
            return $Item->isActive();
        });
    }

    /**
     * Add a child item
     *
     * @param AbstractMenuItem $Item
     */
    public function appendChild(AbstractMenuItem $Item): void
    {
        $this->children[] = $Item;
    }

    //endregion
}