PHP Classes

File: LinkGenerator.php

Recommend this page to a friend!
  Packages of Melanie Wehowski   Link Generator   LinkGenerator.php   Download  
File: LinkGenerator.php
Role: Class source
Content type: text/plain
Description: Class file
Class: Link Generator
Generate HTML for links and forms from templates
Author: By
Last change: Added some default templates
Date: 3 months ago
Size: 8,071 bytes
 

Contents

Class file image Download
<?php

namespace StartDir;

class
LinkGenerator
{
   
/**
     * @var array<string, array<string, string>>
     */
   
private array $templates = [];

    public function
__construct(array $defaultTemplates = [])
    {
       
$this->templates = $defaultTemplates;
    }
   
    public function
addDefaults(){
   
       
//following & followers
   
       
        //mastodon
       
$this->addTemplate(
           
'misskey',
           
'following',
           
'https://{instance}/@{username}/following'
       
);
       
       
$this->addTemplate(
           
'misskey',
           
'followers',
           
'https://{instance}/@{username}/followers'
       
);
       
       
       
       
//mastodon
       
$this->addTemplate(
           
'mastodon',
           
'following',
           
'https://{instance}/@{username}/following'
       
);
       
       
$this->addTemplate(
           
'mastodon',
           
'followers',
           
'https://{instance}/@{username}/followers'
       
);
       
       
//hometown
       
$this->addTemplate(
           
'hometown',
           
'following',
           
'https://{instance}/@{username}/following'
       
);
       
       
$this->addTemplate(
           
'hometown',
           
'followers',
           
'https://{instance}/@{username}/followers'
       
);
       
       
//friendica
       
$this->addTemplate(
           
'friendica',
           
'following',
           
'https://{instance}/profile/{username}/contacts/following'
       
);
       
       
$this->addTemplate(
           
'friendica',
           
'followers',
           
'https://{instance}/profile/{username}/contacts/followers'
       
);
               
       
       
       
       
       
// search
       
$this->addTemplate(
           
'elgg',
           
'search',
           
'https://{instance}/search?q={q}'
       
);
                   
       
$this->addTemplate(
           
'flohmarkt',
           
'search',
           
'https://{instance}/search?q={q}'
       
);
               
       
   
/*
        $this->addTemplate(
            'ecko',
            'search',
            'https://{instance}/search?q={q}'
        );
   
        $this->addTemplate(
            'fedibird',
            'search',
            'https://{instance}/search?q={q}'
        );
        */
       
$this->addTemplate(
           
'hometown',
           
'search',
           
'https://{instance}/search?q={q}'
       
);
       
       
$this->addTemplate(
           
'mastodon',
           
'search',
           
'https://{instance}/search?q={q}'
       
);

       
$this->addTemplate(
           
'friendica',
           
'search',
           
'https://{instance}/search?q={q}'
       
);
       

       
$this->addTemplate(
           
'wordpress',
           
'search',
           
'https://{instance}/?s={s}'
       
);
       

       
$this->addTemplate(
           
'peertube',
           
'search',
           
'https://{instance}/search?search={search}'
       
);
    }


    public function
templateExists(string $software, string $module): bool
   
{
       
$software = strtolower($software);
        return isset(
$this->templates[$software][$module])
            &&
is_string($this->templates[$software][$module])
            &&
$this->templates[$software][$module] !== '';
    }
   
   
    public function
addTemplate(
       
string $software,
       
string $modul,
       
string $template
   
): void {
       
$this->templates[strtolower($software)][$modul] = $template;
    }

    public function
generateLink(
       
string $instance,
       
string $software,
       
string $modul = 'search',
        array
$params = []
    ):
string {
       
$software = strtolower($software);
        if (!isset(
$this->templates[$software][$modul])) {
            throw new \
InvalidArgumentException(
               
sprintf(
                   
'Kein Template f?r Modul "%s" in Software "%s" definiert.',
                   
$modul,
                   
$software
               
)
            );
        }

       
$template = $this->templates[$software][$modul];

       
$replacements = [
           
'{instance}' => rawurlencode($instance),
        ];

        foreach (
$params as $key => $value) {
           
$replacements['{' . $key . '}'] = rawurlencode($value);
        }

       
$result = strtr($template, $replacements);

        if (
preg_match('/\{[a-zA-Z0-9_]+\}/', $result)) {
            throw new \
RuntimeException(
               
'Nicht ersetzte Platzhalter im Template vorhanden: ' . $result
           
);
        }

        return
$result;
    }

 public function
getFormHtml(
   
string $instance,
   
string $software,
   
string $modul = 'search',
   
string $method = 'GET',
    array
$defaultValues = [],
    array
$formAttributes = []
 ):
string {

   
$software = strtolower($software);

    if (!isset(
$this->templates[$software][$modul])) {
        throw new \
InvalidArgumentException(
           
sprintf(
               
'Kein Template f?r Modul "%s" in Software "%s" definiert.',
               
$modul,
               
$software
           
)
        );
    }

   
$template = $this->templates[$software][$modul];

   
// --- Template vorbereiten (nur {instance} ersetzen) ---
   
$preparedUrl = str_replace(
       
'{instance}',
       
rawurlencode($instance),
       
$template
   
);

   
$method = strtoupper($method) === 'POST' ? 'POST' : 'GET';

   
// URL in Bestandteile zerlegen
   
$parsed = parse_url($preparedUrl);

   
$path = $parsed['scheme'] . '://' . $parsed['host']
        . (
$parsed['path'] ?? '');

   
$queryPart = $parsed['query'] ?? '';

   
// --- Query-Placeholder extrahieren ---
   
preg_match_all('/\{([a-zA-Z0-9_]+)\}/', $queryPart, $queryMatches);
   
$queryFields = array_unique($queryMatches[1]);

   
// --- Path-Placeholder extrahieren ---
   
preg_match_all('/\{([a-zA-Z0-9_]+)\}/', $path, $pathMatches);
   
$pathFields = array_unique($pathMatches[1]);

   
// --- Action bestimmen ---
   
$action = $path;

   
// Form-Attribute bauen
   
$attrString = '';
    foreach (
$formAttributes as $key => $value) {
       
$attrString .= sprintf(
           
' %s="%s"',
           
htmlspecialchars($key, ENT_QUOTES),
           
htmlspecialchars($value, ENT_QUOTES)
        );
    }

   
$html = sprintf(
       
'<form method="%s" action="%s"%s>',
       
htmlspecialchars($method, ENT_QUOTES),
       
htmlspecialchars($action, ENT_QUOTES),
       
$attrString
   
);

   
// --- Path-Felder als hidden ---
   
foreach ($pathFields as $field) {

        if (
$field === 'instance') {
            continue;
        }

       
$value = $defaultValues[$field] ?? '';

       
$html .= sprintf(
           
'<input type="hidden" name="%s" value="%s">',
           
htmlspecialchars($field, ENT_QUOTES),
           
htmlspecialchars($value, ENT_QUOTES)
        );
    }

   
// --- Query-Felder als Textfelder ---
   
foreach ($queryFields as $field) {

       
$value = $defaultValues[$field] ?? '';

       
$html .='<span style="position:relative;display:inline-block;">'
           
.sprintf(
           
'<input type="text" name="%s" value="%s" placeholder="&#128269;" ng-model="searchInInstanceFormValue"
        style="padding-right:22px;"
        oninput="this.nextElementSibling.style.display=this.value?\'block\':\'none\';">'
,
           
htmlspecialchars($field, ENT_QUOTES),
           
htmlspecialchars($value, ENT_QUOTES)
        ).
'<span
        onclick="this.previousElementSibling.value=\'\';this.style.display=\'none\';this.previousElementSibling.focus();"
        style="
            display:'
. ($value !== '' ? 'block' : 'none') . ';
            position:absolute;
            right:6px;
            top:50%;
            transform:translateY(-50%);
            cursor:pointer;
            font-weight:bold;
            color:#666;
            user-select:none;
        "
    >?</span>
</span>'
;
    }

   
$html .= '<button type="submit" class="btn-sm btn-info">
      <span ng-show="langIsDefault==true || langShortCode==\'en\'" ng-cloak>Search <span ng-show="searchInInstanceFormValue">for &quot;{{searchInInstanceFormValue }}&quot;</span> on '
.ucfirst($instance).' &#128269;</span>
      <span ng-show="langShortCode==\'de\'" ng-cloak>Auf '
.ucfirst($instance).' <span ng-show="searchInInstanceFormValue">nach &quot;{{searchInInstanceFormValue }}&quot;</span> suchen &#128269;</span>
    </button>'
;
   
$html .= '</form>';

    return
$html;
 }

}