Linkgenerator frage

Anmerkungen, Fragen und Hinweise zur Konfiguration dürfen in diesem Forum gepostet werden. // Notes, questions, and hints on the configuration can be posted here.
Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: Linkgenerator frage

Beitrag von dr.e. » 06.11.2011, 19:12:43

Hallo Werner,
Die fromString methode holt sich den (Registry::retrieve('apf::core', 'CurrentRequestURL') um den url zu erzeugen.
Das war an sich Absicht um die Nachvollziehbarkeit des aktuellen Request zu garantieren. In deinem Fall scheint mir das tatsächlich hinderlich. Sofern es hilft, könnte man dies auch entfernen, so dass du in einem Input-Filter in der Lage bist, eine Manipulation vorzunehmen. Allerdings ist dann nicht mehr gewährleistet, dass das URL-Schema mal eben getauscht werden kann, da du zwischendurch in der Lage bist den Inhalt zu verändern. Eine Abwägung ist also notwendig.
Es wäre hier also schon sehr praktisch, wenn die funktion automatisch alle parameter des $_GET Arrays verarbeitet. Damit wäre es möglich, dass man irgendwo einfach $_GET['add']=null setzten kann und somit die variable raus fliegt. Klar was ich meine?
Erzeugung und Verarbeitung sind mit dem 1.14er-Konzept jedoch getrennt. Das bedeutet, dass du eine Instanz der Klasse Url erzeugen kannst, wie du möchtest, die Verarbeitung wird immer durch eine LinkScheme-Implementierung gesteuert. Vielleicht liegt deine Lösung also eher in der Implementierung eines LinkScheme, das automatisch die $_GET-Parameter nimmt und in die URL schreibt. Kann das eine Lösung sein?
Viele Grüße,
Christian

welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

Re: Linkgenerator frage

Beitrag von welworx » 06.11.2011, 20:09:22

Lösung also eher in der Implementierung eines LinkScheme,
mhm .. ja so könnte man das machen. sprich ich brauche eigentlich nur im link sheme prüfen ob der parameter vorher im $_GET null gesetzt wurde und falls ja ihn raushauen .. Somit brauch ich nur an einer zentralen stelle was zu ändern .. gefällt mir sehr gut :D

Sehe da grad noch einen weiteren vorteil .. ich kann damit und mit einem inputfilter endlich gut mehrsprachige urls erledigen ...

sprich die parameter der applikation anhand einer config datei entsprechend transferieren :D .. das spart stunden und erzeugt übersicht :D *freu*

=> ergo : ja ich glaub die Lösung liegt auch darin :D

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: Linkgenerator frage

Beitrag von dr.e. » 06.11.2011, 20:21:16

Fein, dann hat sich die Diskussion gelohnt. :) Solltest du Hilfe bei der Implementierung brauchen, sag Bescheid. Mehr dazu kannst du in der Doku unter http://adventure-php-framework.org/Seit ... nk-Schemen und im Wiki unter http://wiki.adventure-php-framework.org ... nk-Schemes nachlesen.
Viele Grüße,
Christian

welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

Re: Linkgenerator frage

Beitrag von welworx » 07.11.2011, 02:55:44

Beim versuch das ganze umzusetzen scheitere ich gerade leider an dem punkt an dem ich die Config mit den sprachabhängigen parametern einlesen soll. Damit das funktioniert benötige ich die aktuelle Sprache und den aktuellen context. Wie kann ich die erhalten im Linksheme?

(wenn dich die manuell setzte funktioniert alles wunderbar :D)

LG Werner

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: Linkgenerator frage

Beitrag von dr.e. » 07.11.2011, 23:20:51

Hallo Werner,

das LinkScheme weiß zunächst nichts von den beiden. Sofern du diese Parameter in die Implementierung injizieren möchtest, kannst du das in der Bootstrap-Datei z.B. so tun:

Code: Alles auswählen

import('tools::link', 'LinkGenerator'); 
import('...', 'MyLinkScheme'); 
$scheme = new MyLinkScheme();
$scheme->setContext('...');
$scheme->setLanguage('...')
LinkGenerator::setLinkScheme($scheme); 
Alternativ kannst du diese beiden Parameter in dein Url-Objekt als Parameter einbinden und im LinkScheme eben nicht in die Url einbinden, sondern zur Verarbeitung nutzen. Alternative 3 ist, diese aus einer Action oder der zentralen Front-Controller-Instanz zu beziehen. Du kannst im LinkScheme ja genauso per

Code: Alles auswählen

$fC = Singleton::getInstance('Frontcontroller'); 
den Front-Controller beziehen. Und dieser verrät dir mit

Code: Alles auswählen

$context = $fC->getContext();
$lang = $fC->getLanguage(); 
alles, was du brauchst.

Darf ich fragen, wie diese in die Url-Formatierung eingehen? Vielleicht gibt es auch da eine bessere/einfachere Lösung... :)
Viele Grüße,
Christian

welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

Re: Linkgenerator frage

Beitrag von welworx » 07.11.2011, 23:55:47

Das mit

Code: Alles auswählen

$fC = Singleton::getInstance('Frontcontroller');
$context = $fC->getContext();
$lang = $fC->getLanguage();   
gefällt mir sehr gut. Da meine sprache aber erst in einer action gesetzt wird, wohl aber auch für ihr eltern objekt meine frage hier ob sich das von timeing ausgeht?


Die idee dahinter war, dass ich im system parameter definieren kann wie zb ADDProduct und dieser Parameter dann mittels config je nach sprache zu ProduktHinzufuegen oder so transferiert wird.

Der vorteil bei der methode ist, dass ich so die diversen inc parameter von den importdesign taglibs und vieles mehr verwenden kann und dennoch schöne sprachabhängige urls erhalte.

Wenns fertig ist werd ich das aber eh ins wiki stelln.

LG Werner
Zuletzt geändert von welworx am 08.11.2011, 00:43:15, insgesamt 2-mal geändert.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: Linkgenerator frage

Beitrag von dr.e. » 08.11.2011, 00:07:52

Hallo Werner,
Da meine sprache aber erst in einer action gesetzt wird, wohl aber auch für ihr eltern objekt meine frage hier ob sich das von timeing ausgeht?
Der Zeitpunkt der Link-Generierung ist bei dir vermutlich in der Transformations-Phase zu suchen. Zu diesem Zeitpunkt sind die Actions schon durch (siehe auch http://adventure-php-framework.org/Seit ... Einleitung).
Die idee dahinter war, dass ich im system parameter definieren kann wie zb ADDProduct und dieser Parameter dann mittels config je nach sprache zu ProduktHinzufuegen oder so transferiert wird.
Und das möchtest du im LinkScheme umsetzen? Wenn ja, sehe ich das als sehr gute Möglichkeit an.
Viele Grüße,
Christian

welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

Re: Linkgenerator frage

Beitrag von welworx » 08.11.2011, 00:43:58

gesagt getan (muss noch ausführlich getestet werden .. vorläufig gehts jedenfalls mal)

Der Filter:

Code: Alles auswählen

<?php

/**
 * This filter translate the language dependend input parameternames into their
 * original system names.
 * This filter has to be called after the ChainedGenericInputFilter.
 */
class LanguageDependendParameterFilter implements ChainedContentFilter {

    private $Config;
    private $ConfigNamespace;
    private $ConfigFilename;

    public function __construct($ConfigNamespace, $ConfigFilename) {
        $this->setConfigNamespace($ConfigNamespace);
        $this->setConfigFilename($ConfigFilename);
    }

    /**
     * This filter translates input parameter names to its system equal names.
     * @param FilterChain $chain
     * @param string $input
     * @return The result of the filter execution. 
     */
    public function filter(FilterChain &$chain, $input = null) {

        if (isset($_GET)) {
            $getArray = $_GET;
            $_GET = array();

            foreach ($getArray as $key => $elem) {
                $name = $this->getSystemParameterName($key);
                if ($name !== $key) {
                    unset($_REQUEST[$key]);
                    $_REQUEST[$name] = $elem;
                }
                $_GET[$name] = $elem;
            }
            unset($getArray);
        }
        return $chain->filter($input);
    }

    /**
     * Returns language dependend section of the stored config file.
     * @return Configuration 
     */
    public function getConfig() {
        if ($this->Config === null) {
            $fC = Singleton::getInstance('Frontcontroller');
            $context = $fC->getContext();
            $language = $fC->getLanguage();
            $config = ConfigurationManager::loadConfiguration($this->getConfigNamespace(), $context, $language, Registry::retrieve('apf::core', 'Environment'), $this->getConfigFilename());
            $this->Config = $config->getSection($language);
        }
        return $this->Config;
    }

    public function setConfig($Config) {
        $this->Config = $Config;
    }

    public function getConfigNamespace() {
        return $this->ConfigNamespace;
    }

    public function setConfigNamespace($ConfigNamespace) {
        $this->ConfigNamespace = $ConfigNamespace;
    }

    public function getConfigFilename() {
        return $this->ConfigFilename;
    }

    public function setConfigFilename($ConfigFilename) {
        $this->ConfigFilename = $ConfigFilename;
    }

    /**
     * Falls vorhanden wird der Parameter übersetzt, ansonsten wird er unverändert zurückgegeben.
     * @param string $key
     * @return string 
     */
    public function getSystemParameterName($key) {
        try {
            $config = $this->getConfig();
            $valueKeys = $config->getValueNames();
            foreach ($valueKeys as $valueKey) {
                if ($config->getValue($valueKey) === $key) {
                    return $valueKey;
                }
            }
            return $key;
        } catch (Exception $e) {
            return $key;
        }
    }

}

?>

welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

Re: Linkgenerator frage

Beitrag von welworx » 08.11.2011, 00:45:21

Das Link sheme

Code: Alles auswählen

/**
 * This link scheme implementation is intended to handle rewritten urls
 * that have a generic path structure encoding params and their values.
 * 
 * It also translates the system parameternames to their equals based on the 
 * currend language and the defined config file.
 * 
 * This link scheme is aware of front controller actions to be included into the
 * url by action configuration.
 */
class LanguageDependendParameterLinkSheme extends BasicLinkScheme implements LinkScheme {

    private $Config;
    private $ConfigNamespace;
    private $ConfigFilename;

    public function __construct($ConfigNamespace, $ConfigFilename, $encodeAmpersands = true) {
        $this->setConfigNamespace($ConfigNamespace);
        $this->setConfigFilename($ConfigFilename);
    }

    public function formatLink(Url $url) {
        /*
         * 1.) paremeter aus dem pfad holen
         * 1a) sprachabhängigenParameternamen übersetzten 
         * 2.) mit get abgleichen (damit reihnfolge erhalten bleibt)
         * 3.) gesetzte parameter einbauen
         * 4.) alle parameternamen übersetzten
         * 5.) Link bauen
         */

        // save and reset query to save variable order
        $TranslatedQuery = $url->getQuery();
        $url->setQuery(array());

        //Variable that stores the request parameters.
        $query = array();

        //Parameter to Store action from url and leave it untouched
        $urlAction = '';

        // extract path to separate params and remove actions
        $partsOriginal = explode(self::REWRITE_PARAM_TO_ACTION_DELIMITER, $url->getPath());

        //if Skriptname exists, remove it
        $parts = str_replace($_SERVER['SCRIPT_NAME'], '', $partsOriginal);

        foreach ($parts as $part) {

            // only extract "normal" parameters, avoid actions
            if (strpos($part, '-action') === false) {
                $paths = explode('/', strip_tags($part));
                array_shift($paths);

                // create key => value pairs from the current request
                $x = 0;
                while ($x <= (count($paths) - 1)) {
                    if (isset($paths[$x + 1])) {
                        //get retranslated parameter name
                        $keyName = $this->getSystemParameterName($paths[$x]);

                        //set Parameters null if defined als null in $_GET array
                        if (array_key_exists($keyName, $_GET) && $_GET[$keyName] === null) {
                            $query[$keyName] = null;
                        } else {
                            $query[$keyName] = $paths[$x + 1];
                        }
                    }
                    // increment by 2, because the next offset is the key!
                    $x = $x + 2;
                }
            }
        }

        //translate languagedependent query parameters to system names
        foreach ($TranslatedQuery as $key => $elem) {
            $query[$this->getSystemParameterName($key)] = $elem;
        }
        unset($TranslatedQuery);

        // reset the path to not have duplicate path due to generic param generation
        $url->setPath(null);

        $resultUrl = $this->getFormattedBaseUrl($url);

        //add Scriptname:
        //suchen ob string vorhanden war und falls ja hinzufügen!

        $path = $url->getPath();
        if (!empty($path)) {
            $resultUrl .= $path;
        }

        //Translate parameter Names

        if (count($query) > 0) {
            foreach ($query as $name => $value) {

                if ($value !== null) {
                    if (strpos($name, '-action') === false) {
                        $paramName = $this->getLanguageDependendParameterName($name);
                        $resultUrl.='/' . $paramName . '/' . $value;
                    } else {
                        // action blocks must be separated with group indicator
                        // to be able to parse the parameters
                        $resultUrl .= self::REWRITE_PARAM_TO_ACTION_DELIMITER . $name . '/' . $value;
                    }
                }
            }
        }

        //Add existing url actions
        $resultUrl.=$urlAction;

        // add fc actions
        $actions = $this->getActionsUrlRepresentation(true);
        if (!empty($actions)) {
            $resultUrl .= self::REWRITE_PARAM_TO_ACTION_DELIMITER . $actions;
        }
        unset($query);
        return $resultUrl;
    }

    public function formatActionLink(Url $url, $namespace, $name, array $params = array()) {
        return $this->formatLink(
                        $url->setQueryParameter(
                                $this->formatActionIdentifier($namespace, $name, false), $this->formatActionParameters($params, false)
                        ));
    }

  
    public function getConfig() {
        if ($this->Config === null) {
            $fC = Singleton::getInstance('Frontcontroller');
            $context = $fC->getContext();
            $language = $fC->getLanguage();
            $config = ConfigurationManager::loadConfiguration($this->getConfigNamespace(), $context, $language, Registry::retrieve('apf::core', 'Environment'), $this->getConfigFilename());
            $this->Config = $config->getSection($language);
        }
        return $this->Config;
    }

    public function setConfig($Config) {
        $this->Config = $Config;
    }

    public function getConfigNamespace() {
        return $this->ConfigNamespace;
    }

    public function setConfigNamespace($ConfigNamespace) {
        $this->ConfigNamespace = $ConfigNamespace;
    }

    public function getConfigFilename() {
        return $this->ConfigFilename;
    }

    public function setConfigFilename($ConfigFilename) {
        $this->ConfigFilename = $ConfigFilename;
    }

    public function getLanguageDependendParameterName($key) {
        try {
            $config = $this->getConfig();
            $value = $config->getValue($key);

            if ($value !== '' && $value !== null) {
                return $value;
            } else {
                return $key;
            }
        } catch (Exception $e) {
            return $key;
        }
    }

    /**
     * Falls vorhanden wird der Parameter übersetzt, ansonsten wird er unverändert zurückgegeben.
     * @param string $key
     * @return string 
     */
    public function getSystemParameterName($key) {
        try {
            $config = $this->getConfig();
            $valueKeys = $config->getValueNames();
            foreach ($valueKeys as $valueKey) {
                if ($config->getValue($valueKey) === $key) {
                    return $valueKey;
                }
            }
            return $key;
        } catch (Exception $e) {
            return $key;
        }
    }
}
sehr komisch .. wenn ich das ganze als php code einbaue dann wirds mir rausgelöscht.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: Linkgenerator frage

Beitrag von dr.e. » 25.05.2012, 23:11:02

Hallo Werner,

wenn du Lust & Zeit hast, kannst du zu deinem LinkScheme ein paar Zeilen im Wiki schreiben. Dort sollte die Code-Formatierung kein Problem sein. Ich persönlich finde das Beispiel sehr schön, da es die Flexibilität des Konzeptes zeigt.
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast