Seo.php

<?php

namespace Lia\Addon;

/**
 *
 *
 * Resources for needed seo data/
 * https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started
 * https://ogp.me/
 * https://www.w3schools.com/tags/tag_meta.asp
 * NOT USED https://schema.org
 */
class Seo extends \Lia\Addon {

    public string $fqn = 'lia:server.seo';


    /**
     * array of seo values like:
     * `['title' => 'The Title', 'description'=>'the description', ...]`
     */
    public $seo = [];

    /**
     * array of html like `['title'=>['<title>The Title</title>', '<meta ...'], 'image'=>['<meta property="og:image:alt" ...>']]`
     */
    public $html = [];

    public function init_lia(){
        $lia = $this->lia;
        $lia->methods['seo'] = [$this, 'seo'];
        $lia->methods['seoTitle'] = [$this, 'title'];
        $lia->methods['seoDescription'] = [$this, 'description'];
        $lia->methods['seoImage'] = [$this, 'image'];
        $lia->methods['seoUrl'] = [$this, 'url'];
        $lia->methods['seoMeta'] = [$this, 'meta'];
        $lia->methods['seoSiteName'] = [$this, 'site_name'];
        $lia->methods['getSeoHtml'] = [$this, 'get_html'];
        $lia->methods['addHeadHtml'] = [$this, 'addHeadHtml'];
    }

    public function addHeadHtml($html){
        $this->html[] = [$html];
    }

    /**
     * Shorthand to set seo paramaters from an array. 
     *
     * @param $params an array like `['title'=>'the title', 'description'=>'the descript', 'image'=>['url', 'altText'], 'site_name'=>'Site Name', ...'` 
     *
     * @note Each key corresponds to a method on this class
     * @note Each array value will be expanded as multiple paramaters
     * @note Each string value will be used as a single paramater
     */
    public function seo($params){
        foreach ($params as $key=>$value){
            if (is_array($value))$this->$key(...$value);
            else $this->$key($value);
        }
    }
    public function title($title){
        $this->seo['title'] = $title;
        $this->html['title'] = [
            sprintf('<title>%s</title>', $title),
            sprintf('<meta property="og:title" content="%s" />', $title)
        ];
    }
    /**
     * @TODO make og:type configurable
     */
    public function description($description){
        $this->seo['description'] = $description;
        $this->html['description'] = [
            sprintf('<meta name="description" content="%s" />', $description),
            sprintf('<meta property="og:description" content="%s" />', $description),
            sprintf('<meta property="og:type" content="article" />', $description),
            sprintf('<meta property="twitter:card" content="summary" />', $description),
        ];
    }
    /**
     * Add any meta tag
     * @param $name the name attribute for the meta tag
     * @param $content the content attribute for the meta tag
     */
    public function meta(string $name, string $content){
        $this->html['meta'] = $this->html['meta'] ?? [];
        $this->html['meta'][] = 
            sprintf('<meta name="%s" content="%s" />',$name, $content);
    }
    /**
     * @param $url image url
     * @param $altText alternate text to describe the image
     */
    public function image($url, $altText){
        $this->seo['image'] = $url;
        $this->seo['image:alt'] = $altText;
        
        $this->html['image'] = [
            sprintf('<meta property="og:image" content="%s" />', $url),
            sprintf('<meta property="twitter:image" content="%s" />', $url),
        ];
        $this->html['image:alt'] = [
            sprintf('<meta property="og:image:alt" content="%s" />', $altText),
        ];
    }
    public function url($url){
        $this->seo['url'] = $url;

        $this->html['url'] = [
            sprintf('<link rel="canonical" href="%s" />', $url),
            sprintf('<meta name="og:url" content="%s" />', $url),
        ];
    }
    public function site_name($siteName){
        $this->seo['siteName'] = $siteName;
        $this->html['siteName'] = [
            sprintf('<meta name="og:site_name" content="%s" />', $siteName),
        ];
    }

    /**
     * @param $keywords meta keywords
     */
    public function keywords($keywords){
        $this->seo['keywords'] = $keywords;

        $this->html['keywords'] = [
            sprintf('<meta name="keywords" content="%s" />', $keywords),
        ];
    }

    public function get_html(){
        $full_html = '';
        foreach ($this->html as $html_list){
            foreach ($html_list as $seo_html){
                $full_html .= "$seo_html\n";
            }
        }
        return $full_html;
    }
}