form:time Taglib - einfach Zeitfelder einbinden

Dieser Bereich dient dazu, eure Tricks und Erweiterungen vorzustellen, damit diese auch andere Anwender nutzen können. // This area can be used to publish your tricks and extensions to the APF to be used by other developers.
welworx
Beiträge: 620
Registriert: 27.09.2010, 19:29:44

form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 28.01.2011, 19:08:22

Ich finde dass das Taglib form_taglib_date sehr praktisch ist und daher habe ich soeben selbiges entsprechend modifiziert um es für die Zeitfelder verwenden zu können.

Damit es wie die anderen Formular tags verwendet werden kann, muss es natürlich im selben ordner liegen und auch in allen Dateien eingetragen werden wo bereits der form_taglib_date vorhanden ist.

Ich weiß nicht wie streng ihr mim Copyright seid, aber ich möchte ausdrücklich erwähnen, dass ich den vorhanden Taglib nur verändert und ein wenig erweitert habe. Die ganzen kommentarzeilen habe ich hier wegen der übersichtlichkeit entfernt.

Was genau sollte eigentlich in einem Quelltext an zusatzinfos stehen?

Code: Alles auswählen

class form_taglib_time extends form_control {

    protected $__HoursRange;
    protected $__OffsetNames;
    protected $__MinutesInterval;
    protected $__ShowSeconds = true;

    public function form_taglib_time() {

        // initialize the offset names
        $this->__OffsetNames = array('Hours' => 'Hours', 'Minutes' => 'Minutes', 'Seconds' => 'Seconds');

        // initialize the year range
        $this->__HoursRange['Start'] = 00;
        $this->__HoursRange['End'] = 23;
        $this->__MinutesInterval = 1;
        $this->__ShowSeconds = true;

        // end function
    }

    public function onParseTime() {

        $this->__initHoursRange();
        $this->__initOffsetNames();

        if (!empty($this->__Attributes['minutesinterval'])) {
            $this->__MinutesInterval = (int) $this->__Attributes['minutesinterval'];
        }
        if (!empty($this->__Attributes['showseconds']) && $this->__Attributes['showseconds'] == "false") {
            $this->__ShowSeconds = false;
        }


        $hours = new form_taglib_select();
        $hours->setLanguage($this->__Language);
        $hours->setContext($this->__Context);
        $minutes = new form_taglib_select();
        $minutes->setLanguage($this->__Language);
        $minutes->setContext($this->__Context);

        if ($this->__ShowSeconds != false) {
            $seconds = new form_taglib_select();
            $seconds->setLanguage($this->__Language);
            $seconds->setContext($this->__Context);
        }

        $name = $this->getAttribute('name');

        $hoursIdent = $name . '[' . $this->__OffsetNames['Hours'] . ']';
        $hours->setAttribute('name', $hoursIdent);
        $hours->setAttribute('id', $hoursIdent);

        $minutesIdent = $name . '[' . $this->__OffsetNames['Minutes'] . ']';
        $minutes->setAttribute('name', $minutesIdent);
        $minutes->setAttribute('id', $minutesIdent);

        if ($this->__ShowSeconds != false) {

            $secondsIdent = $name . '[' . $this->__OffsetNames['Seconds'] . ']';
            $seconds->setAttribute('name', $secondsIdent);
            $seconds->setAttribute('id', $secondsIdent);
        }


        for ($i = (int) $this->__HoursRange['Start']; $i <= (int) $this->__HoursRange['End']; $i++) {
            $i = $this->__appendZero($i);
            $hours->addOption($i, $i);
            // end for
        }

        $i = 0;
        while ($i < 60) {
            $i = $this->__appendZero($i);
            $minutes->addOption($i, $i);
            $i = $i + $this->__MinutesInterval;
        }


        if ($this->__ShowSeconds != false) {
            for ($i = 0; $i < 60; $i++) {
                $i = $this->__appendZero($i);
                $seconds->addOption($i, $i);
                // end for
            }
        }

        // preset today's date on startup
        if (!isset($_REQUEST[$name])) {
            $hours->setOption2Selected($this->__appendZero(date('G')));
            $minutes->setOption2Selected($this->__appendZero(date('i')));
            if ($this->__ShowSeconds != false) {
                $seconds->setOption2Selected(date('s'));
            }
            // end if
        }

        // execute the on parse time (important for presetting!)
        $hours->onParseTime();
        $minutes->onParseTime();
        if ($this->__ShowSeconds != false) {
            $seconds->onParseTime();
        }

        // reference the father object and add to the children list
        $hours->setParentObject($this);
        $minutes->setParentObject($this);
        if ($this->__ShowSeconds != false) {
            $seconds->setParentObject($this);
        }
        $this->__Children['h'] = $hours;
        $this->__Children['m'] = $minutes;
        if ($this->__ShowSeconds != false) {
            $this->__Children['s'] = $seconds;
        }

        // execute onAfterAppend() to ensure native APF environment
        $this->__Children['h']->onAfterAppend();
        $this->__Children['m']->onAfterAppend();
        if ($this->__ShowSeconds != false) {
            $this->__Children['s']->onAfterAppend();
        }

        // end function
    }

    private function getId() {
        $id = $this->getAttribute('id');
        if ($id === null) {
            return $this->getAttribute('name');
        }
        return $id;
    }

    public function transform() {


        $buffer = (string) '<span id="' . $this->getId() . '"';

        $style = $this->getAttribute('style');
        if ($style != null) {
            $buffer .= ' style="' . $style . '"';
        }

        $class = $this->getAttribute('class');
        if ($class != null) {
            $buffer .= ' class="' . $class . '"';
        }
        $buffer .= '>';
        foreach ($this->__Children as $section => $DUMMY) {
            $buffer .= $this->__Children[$section]->transform();
            // end foreach
        }

        return $buffer . '</span>';

        // end function
    }

    public function addValidator(AbstractFormValidator &$validator) {
        if ($validator->isActive()) {
            if (!$validator->validate($this->getTime())) {
                $validator->notify();
            }
        }
        // end function
    }

    public function getTime() {
        $hours = $this->getHoursControl()->getSelectedOption()->getAttribute('value');
        $minutes = $this->getMinutesControl()->getSelectedOption()->getAttribute('value');
        if ($this->__ShowSeconds != false) {
            $seconds = $this->getSecondsControl()->getSelectedOption()->getAttribute('value');
            return $hours . ':' . $minutes . ':' . $seconds;
        }
        return $hours . ':' . $minutes;

        // end function
    }

    public function setTime($date) {

        $time = date_parse($date);
        if (count($time['errors']) == 0 && count($time['warnings']) == 0) {
            $this->getHourControl()->setOption2Selected($this->__appendZero($time['hour']));
            $this->getMinutesControl()->setOption2Selected($this->__appendZero($time['minute']));
            if ($this->__ShowSeconds != false) {
                $this->getSecondsControl()->setOption2Selected($time['second']);
            }
        } else {
            throw new FormException('[form_taglib_time::setDate()] Given date "' . $date
                    . '" cannot be parsed (Errors: ' . implode(', ', $time['errors']) . ', warnings: '
                    . implode(', ', $time['warnings']) . ')');
        }
    }

    public function &getHoursControl() {
        return $this->__Children['h'];
        // end function
    }

    public function &getMinutesControl() {
        return $this->__Children['m'];
        // end function
    }

    public function &getSecondsControl() {
        return $this->__Children['s'];
        // end function
    }

    protected function __initHoursRange() {

        // read the range for the year select box
        if (isset($this->__Attributes['hoursrange'])) {

            $hoursrange = explode('-', $this->__Attributes['hoursrange']);

            if (count($hoursrange) == 2) {
                $this->__HoursRange['Start'] = trim($this->__appendZero($hoursrange[0]));
                $this->__HoursRange['End'] = trim($this->__appendZero($hoursrange[1]));
                // end if
            }

            // end if
        }

        // end function
    }

    protected function __initOffsetNames() {

        if (isset($this->__Attributes['offsetnames'])) {

            $offsetNames = explode(';', $this->__Attributes['offsetnames']);

            if (count($offsetNames) == 3) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1],
                    'Seconds' => $offsetNames[2]
                );
                // end if
            }
            if (count($offsetNames) == 2) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1]
                );
                // end if
            }

            // end if
        }

        // end function
    }

    protected function __appendZero($input) {
        if (strlen($input) < 2) {
            $input = '0' . (string) $input;
            // end if
        }
        return $input;
        // end function
    }

    // end class
}

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 28.01.2011, 19:29:01

Mir ist soeben folgendes unerklärliches problem aufgefallen. Wenn ich in ein formular ebenfalls das form_taglib_timecaptcha einbinde, wird der form_taglib_timecaptcha tag nicht richtig transformiert, sondern an seiner stelle der neue taglib. Irgend eine idee an was das liegen könnte?

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 28.01.2011, 19:36:00

Habs gerade geschafft es zu beheben. Man muss die Zeile

Code: Alles auswählen

$this->__TagLibs[] = new TagLib('tools::form::taglib','form','time');
nach der des timecaptcha einbinden.

Find ich irgendwie sehr seltsam.

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 28.01.2011, 23:40:21

Hallo Werner,

ein kombiniertes Feld für Uhrzeiten ist eine sehr gute Idee. Das sollten wir glatt in's APF direkt aufnehmen.
Ich weiß nicht wie streng ihr mim Copyright seid, aber ich möchte ausdrücklich erwähnen, dass ich den vorhanden Taglib nur verändert und ein wenig erweitert habe. Die ganzen kommentarzeilen habe ich hier wegen der übersichtlichkeit entfernt.
Gemäß LGPL sind Erweiterungen des APF ebenfalls unter LGPL zu lizenzieren. In der Lizenz ist vermerkt, dass aus die Header mit dem Lizenz-Vermerk in den Files verbleiben muss. Schreibst du eigenen Code unterliegt dieser grundsätzlich auf der LGPL, nutzt du diesen nicht komerziell, ist die Lizensierung theoretisch unrelevant.
Was genau sollte eigentlich in einem Quelltext an zusatzinfos stehen?
Ich schlage vor, den Code direkt ins APF aufzunehmen - das können wir noch für's Release 1.13 tun -, dann stellt sich die Lizenz-Frage nicht und auch die übrigen Nutzer profitieren davon. Grundsätzlich sollten in einer Klasse eine Klassen- und jeweils Methoden-Header existieren. Stellen an denen du bewusst "magic" treibst bedürfen ebenfalls eines Kommentars, damit der Code-lesende genau nachvollziehen kann, warum du das tust.
Mir ist soeben folgendes unerklärliches problem aufgefallen. Wenn ich in ein formular ebenfalls das form_taglib_timecaptcha einbinde, wird der form_taglib_timecaptcha tag nicht richtig transformiert, sondern an seiner stelle der neue taglib. Irgend eine idee an was das liegen könnte?
Das ist komisch. Die Reihenfolge ist nur relevant, wenn Funktionen davon abhängen (z.B. Validatoren, Filter). In deinem Fall sollte das irrelevant sein.

Mein Vorschlag: du bringst die Klasse auf das besprochene Doku-Niveau und schreibst ein paar Zeilen Doku (siehe http://adventure-php-framework.org/Seit ... um-Control), dann checke ich die Änderungen ins SVN ein.
Viele Grüße,
Christian

APFelsahne
Beiträge: 222
Registriert: 18.03.2010, 13:13:07
Wohnort: Ludwigshafen am Rhein
Kontaktdaten:

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von APFelsahne » 29.01.2011, 10:20:30

Hi!

Super Idee ;) Soweit ich das überflogen habe, ist noch keine Zeitzone mit integriert? Würdest du dies als optionales Attribut noch hinzufügen?

Grüße!
Grüße, Florian
BildAPF-Extension wsCatalyst

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 29.01.2011, 18:14:37

Das mit der zeitzone stimmt. Kann ich gerne noch einbauen.

Wozu genau wird die zeitzone gebraucht? Was soll die bewirken?

Bezüglich der Lizenz sache ist noch ein wenig unklar wie man das macht, wenn man zum bsp einfach ein paar sachen nur verändert, im groben und ganzen aber alles gleich lässt. (sowie bei dem Taglib). Soll ich da jetzt die alten Infos der Methoden einfach übernehmen und dann irgendwie dazu schreiben dass ich die einfach modifiziert habe?


Wenn wir jetzt schon beim thema lizenz sind. Sagen wir mal ich bin so motiviert und bau mir eine software auf apf basis. Kann ich die die dann ohne probleme weiterverscherbeln? Muss ich die irgendwo publizieren? Was muss in den von mir geschiebenen Modulen an lizenz zeugs stehen? Dass ich die lizenz aus den verwendeten dateien nicht entfernen darf ist mir schon klar ....

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 29.01.2011, 19:26:09

Hi Werner,
Bezüglich der Lizenz sache ist noch ein wenig unklar wie man das macht, wenn man zum bsp einfach ein paar sachen nur verändert, im groben und ganzen aber alles gleich lässt. (sowie bei dem Taglib). Soll ich da jetzt die alten Infos der Methoden einfach übernehmen und dann irgendwie dazu schreiben dass ich die einfach modifiziert habe?
Die LGPL schreibt vor, dass Veränderungen am Framework selbst wieder an die Community zurückgespielt werden müssen. Veränderst du Framework-Code (z.B. in der pagecontroller.php), so bist du laut Lizenz verpflichtet, den Code mindestens an den Urheber zu senden oder wahlweise im Forum zu posten. Nutzt du bestehenden Code und modifizierst diesen geringfügig für andere Zwecke muss der Code nicht unter allen Bedingungen zurückfließen, der Lizenz-Header in der Datei muss jedoch erhalten bleiben oder ein Verweis eingeführt werden, der auf die ursprüngliche Lizenz verweist.

In diesen Fall hast du die Lizenz-Regeln dadurch eingehalten, dass du den Code im Forum gepostet und zur Weiterverwendung zur Verfügung gestellt hast. Das passt also. :)
Wenn wir jetzt schon beim thema lizenz sind. Sagen wir mal ich bin so motiviert und bau mir eine software auf apf basis. Kann ich die die dann ohne probleme weiterverscherbeln? Muss ich die irgendwo publizieren? Was muss in den von mir geschiebenen Modulen an lizenz zeugs stehen? Dass ich die lizenz aus den verwendeten dateien nicht entfernen darf ist mir schon klar ....
Das funktioniert ohne Probleme. In einigen Fällen gibt es zwar Einschränkungen der LGPL zu absolut freiem "Verscherbeln", hier bin ich aber offen für ein dual licensing (z.B. nach MIT für's freie "Verscherbeln" und LGPL für strikte Open Source-Software). Letzteres wollte ich ohnehin in den nächsten Versionen einführen um kommerzielle Software noch einfacher bundlen zu können.

Aktuell ist das APF zwar ausschließlich unter LGPL lizensiert, du kannst jedoch ohne weiteres deinen eigenen Code auf dem APF aufsetzen und das Gesamt-Paket verkaufen. Notwendig ist lediglich ein Hinweis auf die Lizenz des APF, die dem APF aber ohnehin immer beiligt. Deine eigene Software darf streng genommen "auch nur" unter LGPL stehen, aber ich bin hier recht entspannt, weil ohnehin über Kurz oder Lang dual licensing ansteht. Unter MIT kannst du dann z.B. deinen Code unter die Apache-Lizenz stellen, während das Framework unter MIT steht. Da ich keinen verklagen werden, der den APF-Code nutzt, ist also alles in Butter. :)
Viele Grüße,
Christian

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 21.02.2011, 09:48:02

Habe unlängst einen Tippfehler in dem Code entdeckt. Hier ist die ausgebesserte Version.

Das mit der Zeitzone würde ich sehr gerne einbauen, aber leider weiß ich nicht was genau damit gemeint ist.


Ansonsten habe ich mal die Copyright vermerke eingefügt. Passt das so?

Code: Alles auswählen

<?php

/**
 * <!--
 * This file is part of the adventure php framework (APF) published under
 * http://adventure-php-framework.org.
 *
 * The APF is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The APF is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the APF. If not, see http://www.gnu.org/licenses/lgpl-3.0.txt.
 * -->
 */

/**
 * @package tools::form::taglib
 * @class form_taglib_time
 *
 * Represents a APF form time control.
 *
 * @author Werner Liemberger
 * @version
 * Version 0.1, 21.2.2011<br />
 */
class form_taglib_time extends form_control {

    protected $__HoursRange;
    protected $__OffsetNames;
    protected $__MinutesInterval;
    protected $__ShowSeconds = true;

    /**
     * @public
     *
     * Initializes the member variables.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function form_taglib_time() {

        // initialize the offset names
        $this->__OffsetNames = array('Hours' => 'Hours', 'Minutes' => 'Minutes', 'Seconds' => 'Seconds');

        // initialize the year range
        $this->__HoursRange['Start'] = 00;
        $this->__HoursRange['End'] = 23;
        $this->__MinutesInterval = 1;
        $this->__ShowSeconds = true;

        // end function
    }

    /**
     * @public
     *
     * Creates the children select fields for the time control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function onParseTime() {

        $this->__initHoursRange();
        $this->__initOffsetNames();

        if (!empty($this->__Attributes['minutesinterval'])) {
            $this->__MinutesInterval = (int) $this->__Attributes['minutesinterval'];
        }
        if (!empty($this->__Attributes['showseconds']) && $this->__Attributes['showseconds'] == "false") {
            $this->__ShowSeconds = false;
        }

        // create select boxes then apply context and language

        $hours = new form_taglib_select();
        $hours->setLanguage($this->__Language);
        $hours->setContext($this->__Context);

        $minutes = new form_taglib_select();
        $minutes->setLanguage($this->__Language);
        $minutes->setContext($this->__Context);

        if ($this->__ShowSeconds != false) {
            $seconds = new form_taglib_select();
            $seconds->setLanguage($this->__Language);
            $seconds->setContext($this->__Context);
        }

        $name = $this->getAttribute('name');

        // apply field names and calculate id to be able access
        // the child elements using JS

        $hoursIdent = $name . '[' . $this->__OffsetNames['Hours'] . ']';
        $hours->setAttribute('name', $hoursIdent);
        $hours->setAttribute('id', $hoursIdent);

        $minutesIdent = $name . '[' . $this->__OffsetNames['Minutes'] . ']';
        $minutes->setAttribute('name', $minutesIdent);
        $minutes->setAttribute('id', $minutesIdent);

        if ($this->__ShowSeconds != false) {
            $secondsIdent = $name . '[' . $this->__OffsetNames['Seconds'] . ']';
            $seconds->setAttribute('name', $secondsIdent);
            $seconds->setAttribute('id', $secondsIdent);
        }


        // set the values for the hours select box
        for ($i = (int) $this->__HoursRange['Start']; $i <= (int) $this->__HoursRange['End']; $i++) {
            $i = $this->__appendZero($i);
            $hours->addOption($i, $i);
            // end for
        }

        // set the values for the minutes select box
        $i = 0;
        while ($i < 60) {
            $i = $this->__appendZero($i);
            $minutes->addOption($i, $i);
            $i = $i + $this->__MinutesInterval;
        }


        // set the values for the seconds select box
        if ($this->__ShowSeconds != false) {
            for ($i = 0; $i < 60; $i++) {
                $i = $this->__appendZero($i);
                $seconds->addOption($i, $i);
                // end for
            }
        }

        // preset today's time on startup
        if (!isset($_REQUEST[$name])) {
            $hours->setOption2Selected($this->__appendZero(date('G')));
            $minutes->setOption2Selected($this->__appendZero(date('i')));
            if ($this->__ShowSeconds != false) {
                $seconds->setOption2Selected(date('s'));
            }
            // end if
        }

        // execute the on parse time (important for presetting!)
        $hours->onParseTime();
        $minutes->onParseTime();
        if ($this->__ShowSeconds != false) {
            $seconds->onParseTime();
        }

        // reference the father object and add to the children list
        $hours->setParentObject($this);
        $minutes->setParentObject($this);
        if ($this->__ShowSeconds != false) {
            $seconds->setParentObject($this);
        }
        $this->__Children['h'] = $hours;
        $this->__Children['m'] = $minutes;
        if ($this->__ShowSeconds != false) {
            $this->__Children['s'] = $seconds;
        }

        // execute onAfterAppend() to ensure native APF environment
        $this->__Children['h']->onAfterAppend();
        $this->__Children['m']->onAfterAppend();
        if ($this->__ShowSeconds != false) {
            $this->__Children['s']->onAfterAppend();
        }

        // end function
    }

    /**
     * @private
     *
     * Returns the id of the time element. In case the developer does not
     * provide the <em>id</em> attribute within the tag definition, the
     * <em>name</em> attribute is used instead.
     *
     * @return string The id to display within the HTML tag.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    private function getId() {
        $id = $this->getAttribute('id');
        if ($id === null) {
            return $this->getAttribute('name');
        }
        return $id;
    }

    /**
     * @public
     *
     * Generated the HTML code of the time control.
     *
     * @return string The HTML code of the time control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function transform() {

        // as of 1.12, the time control should be rendered using a
        // surrounding span do enable the client validator extension
        // to address the control more easily.
        $buffer = (string) '<span id="' . $this->getId() . '"';

        $style = $this->getAttribute('style');
        if ($style != null) {
            $buffer .= ' style="' . $style . '"';
        }

        $class = $this->getAttribute('class');
        if ($class != null) {
            $buffer .= ' class="' . $class . '"';
        }
        $buffer .= '>';
        foreach ($this->__Children as $section => $DUMMY) {
            $buffer .= $this->__Children[$section]->transform();
            // end foreach
        }

        return $buffer . '</span>';

        // end function
    }

    /**
     * @public
     *
     * Re-implements the addValidator() method for the form control due
     * to special behavior.
     *
     * @param AbstractFormValidator $validator The validator to add.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function addValidator(AbstractFormValidator &$validator) {
        if ($validator->isActive()) {
            if (!$validator->validate($this->getTime())) {
                $validator->notify();
            }
        }
        // end function
    }

    /**
     * @public
     *
     * Returns the time with the pattern HH:MM:SS or if ShowSeconds is false with HH:MM
     *
     * @return string Time with pattern HH:MM:SS or if ShowSeconds is false with HH:MM.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function getTime() {
        $hours = $this->getHoursControl()->getSelectedOption()->getAttribute('value');
        $minutes = $this->getMinutesControl()->getSelectedOption()->getAttribute('value');
        if ($this->__ShowSeconds != false) {
            $seconds = $this->getSecondsControl()->getSelectedOption()->getAttribute('value');
            return $hours . ':' . $minutes . ':' . $seconds;
        }
        return $hours . ':' . $minutes;

        // end function
    }

    /**
     * @public
     *
     * Allows you to initialize the time control with a given time (e.g. "08:31" or "08:31:20" or "2011-02-21 08:31:00").
     *
     * @param string $time The time to initialize the control with.
     * @throws FormException In case of date parsing errors.
     *
     * @author Christian Achatz
     * @version
     * Version 0.1, 16.06.2010<br />
     */
    public function setTime($date) {

        $time = date_parse($date);
        if (count($time['errors']) == 0 && count($time['warnings']) == 0) {
            $this->getHoursControl()->setOption2Selected($this->__appendZero($time['hour']));
            $this->getMinutesControl()->setOption2Selected($this->__appendZero($time['minute']));
            if ($this->__ShowSeconds != false) {
                $this->getSecondsControl()->setOption2Selected($time['second']);
            }
        } else {
            throw new FormException('[form_taglib_time::setTime()] Given time "' . $date
                    . '" cannot be parsed (Errors: ' . implode(', ', $time['errors']) . ', warnings: '
                    . implode(', ', $time['warnings']) . ')');
        }
    }

    /**
     * @public
     *
     * Returns a reference on the Dours control of the time control.
     *
     * @return form_taglib_select The hours control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getHoursControl() {
        return $this->__Children['h'];
        // end function
    }

    /**
     * @public
     *
     * Returns a reference on the minutes control of the time control.
     *
     * @return form_taglib_select The minutes control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getMinutesControl() {
        return $this->__Children['m'];
        // end function
    }

    /**
     * @public
     *
     * Returns a reference on the seconds control of the date control.
     *
     * @return form_taglib_select The seconds control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getSecondsControl() {
        return $this->__Children['s'];
        // end function
    }

    /**
     * @protected
     *
     * Initializes the hours range to display.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __initHoursRange() {

        // read the range for the hours select box
        if (isset($this->__Attributes['hoursrange'])) {

            $hoursrange = explode('-', $this->__Attributes['hoursrange']);

            if (count($hoursrange) == 2) {
                $this->__HoursRange['Start'] = trim($this->__appendZero($hoursrange[0]));
                $this->__HoursRange['End'] = trim($this->__appendZero($hoursrange[1]));
                // end if
            }

            // end if
        }

        // end function
    }

    /**
     * @protected
     *
     * Initializes the offset names of the fields.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __initOffsetNames() {

        if (isset($this->__Attributes['offsetnames'])) {

            $offsetNames = explode(';', $this->__Attributes['offsetnames']);

            if (count($offsetNames) == 3) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1],
                    'Seconds' => $offsetNames[2]
                );
                // end if
            }
            if (count($offsetNames) == 2) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1]
                );
                // end if
            }

            // end if
        }

        // end function
    }

    /**
     * @protected
     *
     * Appends a zero for hours, miuntes or seconds numbers without leading zeros.
     *
     * @param int $input The hour, minute or second number.
     * @return string Hour, minute or second number with leading zero.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __appendZero($input) {
        if (strlen($input) < 2) {
            $input = '0' . (string) $input;
            // end if
        }
        return $input;
        // end function
    }

    // end class
}

?>
Für die Doku:

Zeit-Control
Um die Erstellung von Zeit-Auswahl-Menüs zu erleichtern, enthält das APF ein Time-Control. Dieses kann entsprechend den Anforderungen konfiguriert werden.
APF-Template

Code: Alles auswählen

<form:time name="" [hoursrange=""] [offsetnames=""] [showseconds="true|false"] [minutesinterval=""]/>
Beschreibung der Attribute:
  • name: Name des Time-Controls. Über den Namen kann auf das Element zugegriffen werden. (Zeichen: [A-Za-z0-9-_])
  • hoursrange: Range des Stunden-Feldes. Beispiel: 08-21. (Zeichen: [0-9-])
  • offsetnames: Namen der Felder für Stunden, Minuten und Sekunden. Einzelne Felder müssen durch ";" getrennt werden. Beispiel: Stunde:Minute:Sekunde. (Zeichen: [A-Za-z;])
  • showseconds: Hier kann festgelegt werden ob man bei der Ausgabe auch Sekunden haben möchte.
  • minutesinterval: Hier kann definiert werden in welchem Abstand die auswählbaren Minuten vorhanden sind. Man sollte aber darauf achten, dass 60 durch den Wert sinnvoll teilbar ist. Beispiel: 5, 10 oder 15.


PS: Beim Eintragen des Copyright ist mir aufgefallen, dass in der form_taglib_date.php auf zeile 379 osset statt offset steht.

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 22.02.2011, 00:22:18

Hi Werner,

daraus lässt sich doch schon mal eine Doku erstellen. Ich habe die Taglib für 1.13 in das SVN integriert, werde es aber offiziell erst für 1.14 in die Doku aufnehmen, da ich gerade schon die abschließenden Vorbereitungen für 1.13 treffe und es sehr bald released wird.
Das mit der Zeitzone würde ich sehr gerne einbauen, aber leider weiß ich nicht was genau damit gemeint ist.
Diese Thematik ist IMHO nur dann relevant, wenn du die Initialisierung des Feldes vornimmst. Die Server-Zeit kann dann unterschiedlich zur Zeit sein, die der Benutzer tatsächlich in seiner Zone vorfindet. Nehmen wir an, du sitzt in Singapore und die Applikation wird in Deutschland gehostet. Dann könnte man durch Internationalisierung der Applikation ja eine Zeitzone des Benutzers in die Applikation geben und an Hand derer die aktuelle Uhrzeit des Benutzers als Initialisierungswert nutzen.

Aber so oder so ist die Taglib schonmal eine Erweiterung und Bereicherung des APF. Danke dafür! :) Will heißen: sofern das noch niemand braucht, können wir das auch erstmal weglassen und dann on-demand einbauen.
Viele Grüße,
Christian

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 22.02.2011, 22:56:50

Hallo Werner,

ich habe nun auch deine Doku eingebaut und übersetzt. --> http://adventure-php-framework.org/Seit ... it-Control.
Viele Grüße,
Christian

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 26.02.2011, 20:29:05

vielen dank fürs einbauen :D


Hab gestern beim updaten auf die neueste version auch gesehen, dass die time controll sachen noch nicht im svn eingecheckt sind.

Da das mit der zeitzone hab ich jetzt mal weggelasse ;) Kann ich bei zeit (die gerade wenig vorhanden ist) aber gerne mal nachrüsten.
Genau genommen sollte man eigentlich bein initialisieren jene zeitzone verwenden die der browser des clients hat. (wie auch immer man die erhält)

Code: Alles auswählen

<?php

/**
 * <!--
 * This file is part of the adventure php framework (APF) published under
 * http://adventure-php-framework.org.
 *
 * The APF is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The APF is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the APF. If not, see http://www.gnu.org/licenses/lgpl-3.0.txt.
 * -->
 */

/**
 * @package tools::form::taglib
 * @class form_taglib_time
 *
 * Represents a APF form time control.
 *
 * @author Werner Liemberger
 * @version
 * Version 0.1, 21.2.2011<br />
 */
class form_taglib_time extends form_control {

    protected $__HoursRange;
    protected $__OffsetNames;
    protected $__MinutesInterval;
    protected $__ShowSeconds = true;

    /**
     * @public
     *
     * Initializes the member variables.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function form_taglib_time() {

        // initialize the offset names
        $this->__OffsetNames = array('Hours' => 'Hours', 'Minutes' => 'Minutes', 'Seconds' => 'Seconds');

        // initialize the year range
        $this->__HoursRange['Start'] = 00;
        $this->__HoursRange['End'] = 23;
        $this->__MinutesInterval = 1;
        $this->__ShowSeconds = true;

        // end function
    }

    /**
     * @public
     *
     * Creates the children select fields for the time control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function onParseTime() {

        $this->__initHoursRange();
        $this->__initOffsetNames();

        if (!empty($this->__Attributes['minutesinterval'])) {
            $this->__MinutesInterval = (int) $this->__Attributes['minutesinterval'];
        }
        if (!empty($this->__Attributes['showseconds']) && $this->__Attributes['showseconds'] == 'false') {
            $this->__ShowSeconds = false;
        }

        // create select boxes then apply context and language

        $hours = new form_taglib_select();
        $hours->setLanguage($this->__Language);
        $hours->setContext($this->__Context);

        $minutes = new form_taglib_select();
        $minutes->setLanguage($this->__Language);
        $minutes->setContext($this->__Context);

        if ($this->__ShowSeconds != false) {
            $seconds = new form_taglib_select();
            $seconds->setLanguage($this->__Language);
            $seconds->setContext($this->__Context);
        }

        $name = $this->getAttribute('name');

        // apply field names and calculate id to be able access
        // the child elements using JS

        $hoursIdent = $name . '[' . $this->__OffsetNames['Hours'] . ']';
        $hours->setAttribute('name', $hoursIdent);
        $hours->setAttribute('id', $hoursIdent);

        $minutesIdent = $name . '[' . $this->__OffsetNames['Minutes'] . ']';
        $minutes->setAttribute('name', $minutesIdent);
        $minutes->setAttribute('id', $minutesIdent);

        if ($this->__ShowSeconds != false) {
            $secondsIdent = $name . '[' . $this->__OffsetNames['Seconds'] . ']';
            $seconds->setAttribute('name', $secondsIdent);
            $seconds->setAttribute('id', $secondsIdent);
        }


        // set the values for the hours select box
        for ($i = (int) $this->__HoursRange['Start']; $i <= (int) $this->__HoursRange['End']; $i++) {
            $i = $this->__appendZero($i);
            $hours->addOption($i, $i);
            // end for
        }

        // set the values for the minutes select box
        $i = 0;
        while ($i < 60) {
            $i = $this->__appendZero($i);
            $minutes->addOption($i, $i);
            $i = $i + $this->__MinutesInterval;
        }


        // set the values for the seconds select box
        if ($this->__ShowSeconds != false) {
            for ($i = 0; $i < 60; $i++) {
                $i = $this->__appendZero($i);
                $seconds->addOption($i, $i);
                // end for
            }
        }

        // preset today's time on startup
        if (!isset($_REQUEST[$name])) {
            $hours->setOption2Selected($this->__appendZero(date('G')));
            $minutes->setOption2Selected($this->__appendZero(date('i')));
            if ($this->__ShowSeconds != false) {
                $seconds->setOption2Selected(date('s'));
            }
            // end if
        }

        // execute the on parse time (important for presetting!)
        $hours->onParseTime();
        $minutes->onParseTime();
        if ($this->__ShowSeconds != false) {
            $seconds->onParseTime();
        }

        // reference the father object and add to the children list
        $hours->setParentObject($this);
        $minutes->setParentObject($this);
        if ($this->__ShowSeconds != false) {
            $seconds->setParentObject($this);
        }
        $this->__Children['h'] = $hours;
        $this->__Children['m'] = $minutes;
        if ($this->__ShowSeconds != false) {
            $this->__Children['s'] = $seconds;
        }

        // execute onAfterAppend() to ensure native APF environment
        $this->__Children['h']->onAfterAppend();
        $this->__Children['m']->onAfterAppend();
        if ($this->__ShowSeconds != false) {
            $this->__Children['s']->onAfterAppend();
        }

        // end function
    }

    /**
     * @private
     *
     * Returns the id of the time element. In case the developer does not
     * provide the <em>id</em> attribute within the tag definition, the
     * <em>name</em> attribute is used instead.
     *
     * @return string The id to display within the HTML tag.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    private function getId() {
        $id = $this->getAttribute('id');
        if ($id === null) {
            return $this->getAttribute('name');
        }
        return $id;
    }

    /**
     * @public
     *
     * Generated the HTML code of the time control.
     *
     * @return string The HTML code of the time control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function transform() {

        // as of 1.12, the time control should be rendered using a
        // surrounding span do enable the client validator extension
        // to address the control more easily.
        $buffer = (string) '<span id="' . $this->getId() . '"';

        $style = $this->getAttribute('style');
        if ($style != null) {
            $buffer .= ' style="' . $style . '"';
        }

        $class = $this->getAttribute('class');
        if ($class != null) {
            $buffer .= ' class="' . $class . '"';
        }
        $buffer .= '>';
        foreach ($this->__Children as $section => $DUMMY) {
            $buffer .= $this->__Children[$section]->transform();
            // end foreach
        }

        return $buffer . '</span>';

        // end function
    }

    /**
     * @public
     *
     * Re-implements the addValidator() method for the form control due
     * to special behavior.
     *
     * @param AbstractFormValidator $validator The validator to add.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function addValidator(AbstractFormValidator &$validator) {
        if ($validator->isActive()) {
            if (!$validator->validate($this->getTime())) {
                $validator->notify();
            }
        }
        // end function
    }

    /**
     * @public
     *
     * Returns the time with the pattern HH:MM:SS or if ShowSeconds is false with HH:MM
     *
     * @return string Time with pattern HH:MM:SS or if ShowSeconds is false with HH:MM.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function getTime() {
        $hours = $this->getHoursControl()->getSelectedOption()->getAttribute('value');
        $minutes = $this->getMinutesControl()->getSelectedOption()->getAttribute('value');
        if ($this->__ShowSeconds != false) {
            $seconds = $this->getSecondsControl()->getSelectedOption()->getAttribute('value');
            return $hours . ':' . $minutes . ':' . $seconds;
        }
        return $hours . ':' . $minutes;

        // end function
    }

    /**
     * @public
     *
     * Allows you to initialize the time control with a given time (e.g. "08:31" or "08:31:20" or "2011-02-21 08:31:00").
     *
     * @param string $time The time to initialize the control with.
     * @throws FormException In case of date parsing errors.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function setTime($date) {

        $time = date_parse($date);
        if (count($time['errors']) == 0 && count($time['warnings']) == 0) {
            $this->getHoursControl()->setOption2Selected($this->__appendZero($time['hour']));
            $this->getMinutesControl()->setOption2Selected($this->__appendZero($time['minute']));
            if ($this->__ShowSeconds != false) {
                $this->getSecondsControl()->setOption2Selected($time['second']);
            }
        } else {
            throw new FormException('[form_taglib_time::setTime()] Given time "' . $date
                    . '" cannot be parsed (Errors: ' . implode(', ', $time['errors']) . ', warnings: '
                    . implode(', ', $time['warnings']) . ')');
        }
    }

    /**
     * @public
     *
     * Returns a reference on the Dours control of the time control.
     *
     * @return form_taglib_select The hours control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getHoursControl() {
        return $this->__Children['h'];
        // end function
    }

    /**
     * @public
     *
     * Returns a reference on the minutes control of the time control.
     *
     * @return form_taglib_select The minutes control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getMinutesControl() {
        return $this->__Children['m'];
        // end function
    }

    /**
     * @public
     *
     * Returns a reference on the seconds control of the date control.
     *
     * @return form_taglib_select The seconds control.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    public function &getSecondsControl() {
        return $this->__Children['s'];
        // end function
    }

    /**
     * @protected
     *
     * Initializes the hours range to display.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __initHoursRange() {

        // read the range for the hours select box
        if (isset($this->__Attributes['hoursrange'])) {

            $hoursrange = explode('-', $this->__Attributes['hoursrange']);

            if (count($hoursrange) == 2) {
                $this->__HoursRange['Start'] = trim($this->__appendZero($hoursrange[0]));
                $this->__HoursRange['End'] = trim($this->__appendZero($hoursrange[1]));
                // end if
            }

            // end if
        }

        // end function
    }

    /**
     * @protected
     *
     * Initializes the offset names of the fields.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __initOffsetNames() {

        if (isset($this->__Attributes['offsetnames'])) {

            $offsetNames = explode(';', $this->__Attributes['offsetnames']);

            if (count($offsetNames) == 3) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1],
                    'Seconds' => $offsetNames[2]
                );
                // end if
            }
            if (count($offsetNames) == 2) {
                $this->__OffsetNames = array(
                    'Hours' => $offsetNames[0],
                    'Minutes' => $offsetNames[1]
                );
                // end if
            }
            // end if
        }
        // end function
    }

    /**
     * @protected
     *
     * Appends a zero for hours, miuntes or seconds numbers without leading zeros.
     *
     * @param int $input The hour, minute or second number.
     * @return string Hour, minute or second number with leading zero.
     *
     * @author Werner Liemberger
     * @version
     * Version 0.1, 21.2.2011<br />
     */
    protected function __appendZero($input) {
        if (strlen($input) < 2) {
            $input = '0' . (string) $input;
            // end if
        }
        return $input;
        // end function
    }
    // end class
}
?>

Dann muss noch folgendes eingebaut werden:
in html_taglib_form auf zeile 28:

Code: Alles auswählen

import('tools::form::taglib','form_taglib_time');
und in zeile 145:

Code: Alles auswählen

$this->__TagLibs[] = new TagLib('tools::form::taglib','form','time');
Dann habe ich noch in form_taglib_clientlistener folgendes hinzugefügt (bin da aber noch nicht zum testen gekommen, da es aber vom date element übernommen ist sollts gehen):
Zeile 98:

Code: Alles auswählen

             case 'form_taglib_time':
                $jQSelector = 'span[id=\''. $controlName . '\']';
                break;
Und zu guter letzt: form_taglib_getclientvalidator in Zeile 159:

Code: Alles auswählen

            case 'form_taglib_time':
                $jQSelector = 'span[id=\''. $definition['control'] . '\']';
                break;
LG Werner

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 26.02.2011, 20:43:45

Hallo Werner,

die form_taglib_time.php war definitiv schon im SVN enthalten. Ich habe nun lediglich den Tag als bekannten Tag zum Formular hinzugefügt. Aktualisiere mal aus dem SVN, dann sollte das passen.

Was die Client-Listener angeht, müssen wir Ralf nochmal zu Rate ziehen, er hat die Extension geschrieben und sollte nochmal einen Blick auf die Anpassungen werfen. @Ralf: passt das so? Falls ja, würde ich das ins SVN für 1.14 integrieren.
Viele Grüße,
Christian

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 26.02.2011, 20:48:18

ok sehr seltsam ... muss mir das mim svn nochmal genauer ansehen ;)


EDIT: ... alles klar .. hab da was verwechselt :D

EDIT2: Hab gesehen dass du

Code: Alles auswählen

         $this->__TagLibs[] = new TagLib('tools::form::taglib','form','time');
vor dem timecaptcha eingefügt hast. Soweit ich mich erinnere hat das damals nicht funktioniert.

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von dr.e. » 26.02.2011, 20:58:22

Hi,

warum sollte das nicht funktionieren? Welche Fehler hattest du da?
Viele Grüße,
Christian

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

Re: form:time Taglib - einfach Zeitfelder einbinden

Beitrag von welworx » 26.02.2011, 21:18:41

ist schon eine zeit her .. glaube es wurde nicht transformiert ...

steht aber eh schon als 2ter post hier.

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast