[ArrayPager]

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.
Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

[ArrayPager]

Beitrag von MrNiceGuy » 21.12.2009, 18:47:56

Moin moin!

Nach einigen Wochen Arbeit an meinem Projekt und wenig Zeit mich den neuen Angelegenheiten hier im Forum zu widmen möchte ich mich kurz vor Weihnachten doch noch mal melden. Grund hierfür ist eine Erweiterung, die vielleicht den Einen oder Anderen interessieren dürfte, der auf ähnliche Probleme mit dem APF-Pager gestoßen ist wie ich.

Kurz zur Vorgeschichte: Ich nutze dynamisch zusammengesetzte Queries zur Abfrage von Datensätzen. Der im APF enthaltene Pager unterstützt aktuell lediglich die Verwendung von Statement-Files, was für meinen Anwendungsfall jedoch nicht ausreichend ist, da lediglich Feldinhalte mittels Platzhalter in die Statement-Files eingebunden werden können. Sobald man jedoch dynamisch die abzufragenden Felder oder die Abfrage-Bedingungen (WHERE) bearbeiten muss stößt man hier an eine Grenze der vom Pager abgedeckten Möglichkeiten.

Meine Idee war es nun also den Pager als Grundlage zu verwenden aber bei der Quelle möglichst unabhängig zu sein. Entsprechend habe ich mich für eine etwas andere Art der Verarbeitung entschieden. Bei dieser Methode wird über eine ManagerFabric ein Manager erzeugt, der eine bestimmte Konfiguration übergeben bekommt. Hierbei definiert die Konfiguration jedoch nicht den Inhalt des Pagers, sondern lediglich die Eckdaten (z.B. welches Template, wieviele Einträge/Seite, etc.). Der Manager kann dann benutzt werden, um Daten für einen Pager zu registrieren und aus den registrierten Daten den Pager erstellen zu lassen bzw. sich die Ergebnisse davon zurückgeben zu lassen.

Einziger Punkt, der hier beachtung finden muss: Es wird lediglich ein Array benötigt, das in der ersten Ebene die einzelnen Beiträge darstellt. So kann man ein ein- oder auch mehrdimensionales Array verwenden und ist frei in der Möglichkeit einfache Texte, Objekte oder aber weitere Arrays als Daten zu behandeln. Die Daten werden hierbei immer in der Session gespeichert was den einfachen Vorteil bietet das Caching für Geschwindigkeitsvorteile zu nutzen, wenn dies gewünscht ist. Ansonsten kann auch ohne Probleme bei jedem Aufruf das Daten-Array erneut registriert werden, sodass das Alte überschrieben wird.

Ich werde erst ein mal kurz auf die Struktur und die Konfigurationen eingehen, bevor ich dann zu den Scripten komme:

extensions/arraypager/biz/ArrayPagerManager.php
extensions/arraypager/biz/ArrayPagerManagerFabric.php
extensions/arraypager/data/ArrayPagerMapper.php
extensions/arraypager/pres/documentcontroller/ArrayPager.php
extensions/arraypager/pres/templates/ArrayPager.php

Zur Konfiguration benötigt man zwei Dateien, eine für die Sprache und eine für die Pager ansich. Namespace ist "extensions::arraypager" und der Name jeweils "language" bzw. "arraypager".

Die Sprachdatei sieht wie folgt aus:

Code: Alles auswählen

[de]
DisplayNEntriesPerPage = "Einträge pro Seite anzeigen"
DisplayNextPage = "Nächste Seite anzeigen"
DisplayPreviousPage = "Vorherige Seite anzeigen"
DisplayPage = "Zeige Seite"
Entries = "Einträge/Seite"
Hier ist mir bei der Entwicklung aufgefallen, dass der größte Teil des Pagers statisch in Deutsch war und nur ein kleiner Teil "dynamisch" in Deutsch/Englisch (durch 2 HTML-Templates) -> etwas unschön.

Die Konfiguration sieht wie folgt aus:

Code: Alles auswählen

[PagerSection]
Pager.DesignNamespace = "extensions::pager::pres::templates"
Pager.DesignTemplate = "pager"
[Pager.Entries = "10"]
[Pager.ParameterPage = "page"]
[Pager.EntriesChangeable = "false|true"]
[Pager.ParameterEntries = "entries"]
[Pager.EntriesPossible = "5|10|15"]
Hierbei sind grundsätzlich erstmal nur 2 Angaben Pflicht: Namespace und Template für das Template zur Ausgabe. Die PagerSection gibt dabei also lediglich das Aussehen vor, was es möglich macht mehrere Designs zu verwenden und für einen Pager lediglich über die Angabe der PagerSection (der Init-Parameter bei Verwendung der ManagerFabric) das Aussehen zu steuern.
Optional hingegen sind:
  • Entries (Anzahl Beiträge/Seite, Standardwert: 10)
  • ParameterPage (der Request-Parameter zur Manipulation der Seite, Standardwert: "page")
  • EntriesChangeable (darf die Anzahl Beiträge/Seite geändert werden? Standardwert: FALSE)
  • ParameterEntries (im Fall von EntriesChangeable=true der Request-Parameter zur Manipulation, Standardwert: "entries")
  • EntriesPossible (im Fall von EntriesChangeable=true eine durch Pipes getrennte Liste der möglichen Auswahlwerte, Standardwert: "5|10|15")
Die Scripte basieren auf dem APF-Pager und ähneln vom Inhalt her entsprechend. Dennoch habe ich die Verarbeitung um einige Dinge deutlich verändern müssen. Ich hoffe dennoch, dass der Code einfach genug ist ihn ohne große Kommentare nachvollziehen zu können.

ArrayPagerManager.php:

Code: Alles auswählen

<?php
import ('extensions::arraypager::data',
        'ArrayPagerMapper'
        );
import ('tools::request',
        'RequestHandler'
        );

/**
 * @namespace extensions::arraypager::biz
 * @class ArrayPagerManager
 *
 * Represents a concrete pager.
 *
 * @author Lutz Mahlstedt
 * @version
 * Version 0.1, 15.12.2009<br />
 */
final class ArrayPagerManager extends coreObject
{
  private $__PagerConfig = NULL;

  private $__AnchorName = NULL;

  public function ArrayPagerManager ()
  {
  }

  /**
   * @public
   *
   * Initializes the pager. Loads the desired config section.
   *
   * @param string $initParam the name of the config section.
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function init ($stringParameter)
  {
    // initialize the config
    $objectConfiguration = $this->__getConfiguration ('extensions::arraypager',
                                                      'arraypager'
                                                      );

    $arrayParameter = array ('Pager.ParameterPage'    => 'page',
                             'Pager.ParameterEntries' => 'entries',
                             'Pager.Entries'          => 10,
                             'Pager.EntriesPossible'  => '5|10|15'
                             );

    $this->__PagerConfig = array_merge ($arrayParameter,
                                        $objectConfiguration->getSection ($stringParameter)
                                        );

    unset ($objectConfiguration);

    if (isset ($this->__PagerConfig['Pager.EntriesChangeable']) === TRUE
    AND $this->__PagerConfig['Pager.EntriesChangeable']         ==  'true'
        )
    {
      $this->__PagerConfig['Pager.EntriesChangeable'] = TRUE;
    }
    else
    {
      $this->__PagerConfig['Pager.EntriesChangeable'] = FALSE;
    }

    $this->__PagerConfig['Pager.Entries'] = intval ($this->__PagerConfig['Pager.Entries']);
  }

  /**
   *  @protected
   *
   *  Returns the mapper.
   *
   *  @return boolean True if pager exists, otherwise false
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  protected function &__getDataMapper ()
  {
    return $this->__getServiceObject ('extensions::arraypager::data',
                                      'ArrayPagerMapper'
                                      );
  }

  /**
   * @public
   *
   * @param string $stringPager name of the pager
   * @param integer $integerPage optional parameter for current page
   * @param integer $integerEntries optional parameter for entries per page
   * @return mixed[] List of entrys for the current page
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function loadEntries ($stringPager,
                               $integerPage    = NULL,
                               $integerEntries = NULL
                               )
  {
    $objectArrayPagerMapper = $this->__getDataMapper ();

    $arrayData = $objectArrayPagerMapper->loadEntries ($stringPager);

    if (is_array ($arrayData) === TRUE)
    {
      if ($integerPage === NULL)
      {
        $integerPage = intval (RequestHandler::getValue ($this->__PagerConfig['Pager.ParameterPage'],
                                                         1
                                                         )
                               );

        if ($integerPage <= 0)
        {
          $integerPage = 1;
        }
      }

      if ($integerEntries === NULL)
      {
        if ($this->__PagerConfig['Pager.EntriesChangeable'] === TRUE)
        {
          $integerEntries = intval (RequestHandler::getValue ($this->__PagerConfig['Pager.ParameterEntries'],
                                                              $this->__PagerConfig['Pager.Entries']
                                                              )
                                    );
        }
        else
        {
          $integerEntries = 0;
        }

        if ($integerEntries <= 0)
        {
          $integerEntries = $this->__PagerConfig['Pager.Entries'];
        }
      }

      return array_slice ($arrayData,
                          (($integerPage - 1) * $integerEntries),
                          $integerEntries,
                          TRUE
                          );
    }
    else
    {
      trigger_error ('[ArrayPagerManager->loadEntries()] There is no pager named "'.$stringPager.'" registered!',
                     E_USER_WARNING
                     );
    }
  }

  /**
   * @public
   *
   * @param string $stringPager name of the pager
   * @return string The HTML representation of the pager
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function getPager ($stringPager)
  {
    $stringOutput = '';

    $objectArrayPagerMapper = $this->__getDataMapper ();

    $arrayData = $objectArrayPagerMapper->loadEntries ($stringPager);

    if (is_array ($arrayData) === TRUE)
    {
      if (is_array ($arrayData) === TRUE
      AND count ($arrayData)    >   0
          )
      {
        // create pager page
        $objectPager = new Page();

        // apply context and language (form configuration purposes!)
        $objectPager->set ('Language',
                           $this->__Language
                           );
        $objectPager->set ('Context',
                           $this->__Context
                           );

        // load the configured design
        $objectPager->loadDesign ($this->__PagerConfig['Pager.DesignNamespace'],
                                  $this->__PagerConfig['Pager.DesignTemplate']
                                  );

        // add the necessary config params and pages
        $objectDocument = $objectPager->getByReference ('Document');

        $objectDocument->setAttribute ('Config',
                                       array ('ParameterPage'     => $this->__PagerConfig['Pager.ParameterPage'],
                                              'ParameterEntries'  => $this->__PagerConfig['Pager.ParameterEntries'],
                                              'Entries'           => RequestHandler::getValue ($this->__PagerConfig['Pager.ParameterEntries'],
                                                                                               $this->__PagerConfig['Pager.Entries']
                                                                                               ),
                                              'EntriesPossible'   => $this->__PagerConfig['Pager.EntriesPossible'],
                                              'EntriesChangeable' => $this->__PagerConfig['Pager.EntriesChangeable']
                                              )
                                       );

        $objectDocument->setAttribute ('DataCount',
                                       count ($arrayData)
                                       );

        // add the anchor if desired
        if ($this->__AnchorName !== NULL)
        {
          $objectDocument->setAttribute ('AnchorName',
                                         $this->__AnchorName
                                         );
        }

        $stringOutput = $objectPager->transform ();
      }
    }
    else
    {
      trigger_error ('[ArrayPagerManager->getPager()] There is no pager named "'.$stringPager.'" registered!',
                     E_USER_WARNING
                     );
    }

    return $stringOutput;
  }

  /**
   *  @public
   *
   *  Sets the anchor name.
   *
   *  @param string $stringAnchorName The name of the desired anchor.
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function setAnchorName ($stringAnchorName = NULL)
  {
    $this->__AnchorName = $stringAnchorName;
  }

  /**
   *  @public
   *
   *  Returns the anchor name.
   *
   *  @return string The name of the anchor
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function getAnchorName ()
  {
    return $this->__AnchorName;
  }

  /**
   * @public
   *
   * @param string $stringPager name of the pager
   * @param array $arrayData the data-list
   * @return string[] Url params of the pager.
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function registerPager ($stringPager,
                                 &$arrayData
                                 )
  {
    $objectArrayPagerMapper = $this->__getDataMapper ();

    $objectArrayPagerMapper->registerEntries ($stringPager,
                                              $arrayData
                                              );
  }

  /**
   * @public
   *
   * @param string $stringPager name of the pager
   * @param array $arrayData the data-list
   * @return string[] Url params of the pager.
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function unregisterPager ($stringPager)
  {
    $objectArrayPagerMapper = $this->__getDataMapper ();

    $objectArrayPagerMapper->unregisterEntries ($stringPager);
  }

  /**
   * @public
   *
   * Returns whether pager exists or not.
   *
   * @param string $stringPager name of the pager
   * @return boolean True if pager exists, otherwise false
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function checkPager ($stringPager)
  {
    $booleanReturn = FALSE;

    $objectArrayPagerMapper = $this->__getDataMapper ();

    $booleanReturn = $objectArrayPagerMapper->checkPager ($stringPager);

    return $booleanReturn;
  }

  /**
   * @public
   *
   * Returns whether page is defined.
   *
   * @return boolean True if page is defined, otherwise false
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function checkPage ()
  {
    $booleanReturn = FALSE;

    $mixedData = RequestHandler::getValue ($this->__PagerConfig['Pager.ParameterPage'],
                                           FALSE
                                           );

    if ($mixedData !== FALSE)
    {
      $booleanReturn = TRUE;
    }

    return $booleanReturn;
  }
}
?>
ArrayPagerManagerFabric.php:

Code: Alles auswählen

<?php
import ('extensions::arraypager::biz',
        'ArrayPagerManager'
        );

/**
 * @namespace extensions::arraypager::biz
 * @class ArrayPagerManagerFabric
 *
 * Implements the factory of the array-pager manager. Initializes concrete ArrayPagerManager
 * instances and caches them for futher usage.
 * Application sample:
 * <pre>$aPMF = $this->__getServiceObject ('extensions::arraypager::biz','ArrayPagerManagerFabric');
 * $aPM = $aPMF->getArrayPagerManager ('{ConfigSection}');</pre>
 *
 * @author Lutz Mahlstedt
 * @version
 * Version 0.1, 21.12.2009<br />
 */
final class ArrayPagerManagerFabric extends coreObject
{
  /**
   * @private
   * Cache list if concrete pager manager instances.
   */
  private $__Pager = array();

  /**
   * @public
   *
   * Returns a reference on the desired pager manager. Initializes newly created ones.
   *
   * @param string $configString The configuration/initialization string (configuration section name).
   * @return ArrayPagerManager Reference on the desired PagerManager instance.
   *
   * @author Lutz Mahlstedt
   * @version
   * Version 0.1, 21.12.2009<br />
   */
  public function &getArrayPagerManager ($stringConfig)
  {
    // create cache key
    $stringPagerHash = md5 ($stringConfig);

    // initialize desired pager lazily
    if (isset ($this->__Pager[$stringPagerHash]) === FALSE)
    {
      $this->__Pager[$stringPagerHash] = $this->__getAndInitServiceObject ('extensions::arraypager::biz',
                                                                           'ArrayPagerManager',
                                                                           $stringConfig,
                                                                           'NORMAL'
                                                                           );
    }

    return $this->__Pager[$stringPagerHash];
  }
}
?>
ArrayPagerMapper.php:

Code: Alles auswählen

<?php
import ('core::session',
        'SessionManager'
        );

/**
 *  @namespace extensions::arraypager::data
 *  @class ArrayPagerMapper
 *
 *  Represents the data layer of the array-pager.
 *
 *  @author Lutz Mahlstedt
 *  @version
 *  Version 0.1, 21.12.2009<br />
 */
final class ArrayPagerMapper extends coreObject
{
  public function ArrayPagerMapper ()
  {
  }

  /**
   *  @protected
   *
   *  Returns the session key.
   *
   *  @param string $stringPager name of the pager
   *  @return string $stringSessionKey the desired session key
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  protected function __getSessionKey ($stringPager)
  {
    return 'ArrayPagerMapper_'.md5 ($stringPager);
  }

  /**
   *  @public
   *
   *  Returns the number of entries of the desired object.
   *
   *  @param string $stringPager name of the pager
   *  @return integer $integerEntriesCount the number of entries
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function getEntriesCount ($stringPager)
  {
    $integerEntriesCount = count ($this->loadEntries ($stringPager));

    return $integerEntriesCount;
  }

  /**
   *  @public
   *
   *  Returns a list of the objects, that should be loaded for the current page.
   *
   *  @param string $stringPager name of the pager
   *  @return array $arrayEntries a list of entries
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function loadEntries ($stringPager)
  {
    $objectSession = new SessionManager ('extensions::arraypager::biz');
    $stringSessionKey = $this->__getSessionKey ($stringPager);
    $arrayEntries = $objectSession->loadSessionData ($stringSessionKey);

    return $arrayEntries;
  }

  /**
   *  @public
   *
   *  @param string $stringPager name of the pager
   *  @return array $arrayEntries a list of entries
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function registerEntries ($stringPager,
                            $arrayData
                            )
  {
    $objectSession = new SessionManager ('extensions::arraypager::biz');
    $stringSessionKey = $this->__getSessionKey ($stringPager);
    $objectSession->saveSessionData ($stringSessionKey,
                                     $arrayData
                                     );
  }

  /**
   *  @public
   *
   *  @param string $stringPager name of the pager
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function unregisterEntries ($stringPager)
  {
    $objectSession = new SessionManager ('extensions::arraypager::biz');
    $stringSessionKey = $this->__getSessionKey ($stringPager);
    $objectSession->deleteSessionData ($stringSessionKey);
  }

  /**
   *  @public
   *
   *  @param string $stringPager name of the pager
   *  @return boolean $mixedData whether pager exists or not
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 21.12.2009<br />
   */
  public function checkPager ($stringPager)
  {
    $objectSession = new SessionManager ('extensions::arraypager::biz');
    $stringSessionKey = $this->__getSessionKey ($stringPager);
    $mixedData = $objectSession->loadSessionData ($stringSessionKey);

    $booleanExists = FALSE;

    if ($mixedData !== FALSE)
    {
      $booleanExists = TRUE;
    }

    return $booleanExists;
  }
}
?>
ArrayPager.php:

Code: Alles auswählen

<?php
import ('tools::link',
        'FrontcontrollerLinkHandler'
        );
import ('tools::request',
        'RequestHandler'
        );

/**
 *  @namespace extensions::arraypager::pres::documentcontroller
 *  @class ArrayPager
 *
 *  Implementiert den DocumentController für den ArrayPagerManager. Folgende Features sind enthalten<br />
 *  <br />
 *    - Anzeige der Seiten<br />
 *    - Vor- & Zurück-Button<br />
 *    - Dynamisches Wählen der Anzahl der Einträge pro Seite<br />
 *  <br />
 *
 *  @author Lutz Mahlstedt
 *  @version
 *  Version 0.1, 20.12.2009<br />
 */
class ArrayPager extends baseController
{
  private $_LOCALS;

  function ArrayPager ()
  {
  }

  /**
   *  @public
   *
   *  Implementiert die abstrakte Methode 'transformContent'.<br />
   *
   *  @author Lutz Mahlstedt
   *  @version
   *  Version 0.1, 20.12.2009<br />
   */
  function transformContent ()
  {
    // LOCALS füllen
    $this->_LOCALS = array ($this->__Attributes['Config']['ParameterEntries'] => $this->__Attributes['Config']['Entries']);

    if ($this->__Attributes['Config']['EntriesChangeable'] === TRUE)
    {
      $this->_LOCALS = RequestHandler::getValues ($this->_LOCALS);
    }

    // Pager leer zurückgeben, falls keine Seiten vorhanden sind.
    if ($this->__Attributes['DataCount'] == 0)
    {
      // Content des aktuellen Designs leeren
      $this->__Content = '';

      // Funktion verlassen
      return '';
    }

    $objectBenchmark = Singleton::getInstance ('BenchmarkTimer');
    $objectBenchmark->start ('ArrayPager');

    // Anzahl der Einträge
    $integerEntriesCount = $this->__Attributes['Config']['Entries'];

    // Anzahl der Seiten generieren
    $integerPageCount = ceil ($this->__Attributes['DataCount'] / $integerEntriesCount);

    // Aktuelle Seite generieren
    $integerCurrentPage = intval (RequestHandler::getValue ($this->__Attributes['Config']['ParameterPage'],
                                                            1
                                                            )
                                  );

    // Puffer initialisieren
    $stringBuffer = '';

    for ($integerPage = 1;
         $integerPage <= $integerPageCount;
         $integerPage++
         )
    {
      if ($integerPage == $integerCurrentPage)
      {
        // Referenz auf Template holen
        $objectTemplate = $this->__getTemplate ('Page_Selected');
      }
      else
      {
        // Referenz auf Template holen
        $objectTemplate = $this->__getTemplate ('Page');
      }

      $stringURL = FrontcontrollerLinkHandler::generateLink ($_SERVER['REQUEST_URI'],
                                                             array ($this->__Attributes['Config']['ParameterPage'] => $integerPage)
                                                             );

      // Pager zusammenbauen
      if (isset ($this->__Attributes['AnchorName']) === TRUE)
      {
        $objectTemplate->setPlaceHolder ('URL',
                                         $stringURL.'#'.$this->__Attributes['AnchorName']
                                         );
      }
      else
      {
        $objectTemplate->setPlaceHolder ('URL',
                                         $stringURL
                                         );
      }

      $objectTemplate->setPlaceHolder ('Page',
                                       $integerPage
                                       );

      // Template transformieren
      $stringBuffer .= $objectTemplate->transformTemplate ();

      unset ($objectTemplate,
             $stringURL
             );
    }

    unset ($integerPage);

    // Puffer in Inhalt einsetzen
    $this->setPlaceHolder ('Pager',
                           $stringBuffer
                           );

    unset ($stringBuffer);

    // VorherigeSeite
    if ($integerCurrentPage > 1)
    {
      // Template vorherige Seite ausgeben
      $objectTemplatePreviousPage = $this->__getTemplate ('PreviousPage_Active');

      // Link generieren
      $stringURL = FrontcontrollerLinkHandler::generateLink ($_SERVER['REQUEST_URI'],
                                                             array ($this->__Attributes['Config']['ParameterPage'] => ($integerCurrentPage - 1))
                                                             );

      if (isset ($this->__Attributes['AnchorName']) === TRUE)
      {
        $objectTemplatePreviousPage->setPlaceHolder ('URL',
                                                     $stringURL.'#'.$this->__Attributes['AnchorName']
                                                     );
      }
      else
      {
        $objectTemplatePreviousPage->setPlaceHolder ('URL',
                                                     $stringURL
                                                     );
      }

      unset ($stringURL);
    }
    else
    {
      // Template vorherige Seite (inaktiv) ausgeben
      $objectTemplatePreviousPage = $this->__getTemplate ('PreviousPage_Inactive');
    }

    $this->setPlaceHolder ('PreviousPage',
                           $objectTemplatePreviousPage->transformTemplate ()
                           );

    unset ($objectTemplatePreviousPage);

    // NaechsteSeite
    if ($integerCurrentPage < $integerPageCount)
    {
      // Link generieren
      $stringURL = FrontcontrollerLinkHandler::generateLink ($_SERVER['REQUEST_URI'],
                                                             array ($this->__Attributes['Config']['ParameterPage'] => ($integerCurrentPage + 1))
                                                             );

      $objectTemplateNextPage = $this->__getTemplate ('NextPage_Active');

      if (isset ($this->__Attributes['AnchorName']) === TRUE)
      {
        $objectTemplateNextPage->setPlaceHolder ('URL',
                                                 $stringURL.'#'.$this->__Attributes['AnchorName']
                                                 );
      }
      else
      {
        $objectTemplateNextPage->setPlaceHolder ('URL',
                                                 $stringURL
                                                 );
      }

      unset ($stringURL);
    }
    else
    {
      $objectTemplateNextPage = $this->__getTemplate ('NextPage_Inactive');
    }

    $this->setPlaceHolder ('NextPage',
                           $objectTemplateNextPage->transformTemplate ()
                           );

    unset ($objectTemplateNextPage);

    if ($this->__Attributes['Config']['EntriesChangeable'] === TRUE)
    {
      // Einträge / Seite
      $arrayEntries = explode ('|',
                               $this->__Attributes['Config']['EntriesPossible']
                               );
      $stringBuffer = '';

      foreach ($arrayEntries AS &$integerEntries)
      {
        if ($this->_LOCALS[$this->__Attributes['Config']['ParameterEntries']] == $integerEntries)
        {
          $objectTemplateEntries = $this->__getTemplate ('Entries_Active');
        }
        else
        {
          $objectTemplateEntries = $this->__getTemplate ('Entries_Inactive');
        }

        // Link generieren
        $stringURL = FrontcontrollerLinkHandler::generateLink ($_SERVER['REQUEST_URI'],
                                                               array ($this->__Attributes['Config']['ParameterPage']    => 1,
                                                                      $this->__Attributes['Config']['ParameterEntries'] => $integerEntries
                                                                      )
                                                               );

        if (isset ($this->__Attributes['AnchorName']) === TRUE)
        {
          $objectTemplateEntries->setPlaceHolder ('URL',
                                                  $stringURL.'#'.$this->__Attributes['AnchorName']
                                                  );
        }
        else
        {
          $objectTemplateEntries->setPlaceHolder ('URL',
                                                  $stringURL
                                                  );
        }

        unset ($stringURL);

        // Anzahl einsetzen
        $objectTemplateEntries->setPlaceHolder ('Entries',
                                                $integerEntries
                                                );

        // Template in Puffer einsetzen
        $stringBuffer .= $objectTemplateEntries->transformTemplate();

        unset ($objectTemplateEntries);
      }

      $objectTemplateEntries = $this->__getTemplate ('Entries');

      $objectTemplateEntries->setPlaceHolder ('Entries',
                                              $stringBuffer
                                              );

      unset ($stringBuffer);

      $this->setPlaceHolder ('Entries',
                             $objectTemplateEntries->transformTemplate ()
                             );

      unset ($objectTemplateEntries);
    }

    // Timer stoppen
    $objectBenchmark->stop ('ArrayPager');
  }
}
?>
ArrayPager.html:

Code: Alles auswählen

<@controller namespace="extensions::arraypager::pres::documentcontroller" file="ArrayPager" class="ArrayPager" @>
<div style="width: 100%; border: 0px solid black; text-align: left; padding-bottom: 2px;">
  <html:placeholder name="PreviousPage" /><html:placeholder name="Pager" /><html:placeholder name="NextPage" />
  <html:placeholder name="Entries" />
</div>
<br />

<html:template name="Page_Selected">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:getstring namespace="extensions::arraypager" config="language" entry="DisplayPage" /> <template:placeholder name="Page" />"><font style="font-size: 16px; font-weight: bold;"><template:placeholder name="Page" /></font></a>&nbsp;&nbsp;
</html:template>

<html:template name="Page">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:getstring namespace="extensions::arraypager" config="language" entry="DisplayPage" /> <template:placeholder name="Page" />"><template:placeholder name="Page" /></a>&nbsp;&nbsp;
</html:template>

<html:template name="PreviousPage_Active">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:getstring namespace="extensions::arraypager" config="language" entry="DisplayPreviousPage" />"><font style="font-size: 14px;">&laquo;</font></a>&nbsp;&nbsp;
</html:template>

<html:template name="PreviousPage_Inactive">
  <font style="font-size: 14px;">&laquo;</font>&nbsp;&nbsp;
</html:template>

<html:template name="NextPage_Active">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:getstring namespace="extensions::arraypager" config="language" entry="DisplayNextPage" />"><font style="font-size: 14px;">&raquo;</font></a>
</html:template>

<html:template name="NextPage_Inactive">
  <font style="font-size: 14px;">&raquo;</font>
</html:template>

<html:template name="Entries_Active">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:placeholder name="Entries" /> <template:getstring namespace="extensions::arraypager" config="language" entry="DisplayNEntriesPerPage" />"><strong><template:placeholder name="Entries" /></strong></a> |
</html:template>

<html:template name="Entries_Inactive">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <a href="<template:placeholder name="URL" />" title="<template:placeholder name="Entries" /> <template:getstring namespace="extensions::arraypager" config="language" entry="DisplayNEntriesPerPage" />"><template:placeholder name="Entries" /></a> |
</html:template>

<html:template name="Entries">
<template:addtaglib namespace="tools::html::taglib" prefix="template" class="getstring" />
  <br />
  <font style="font-size: 9px;"><template:getstring namespace="extensions::arraypager" config="language" entry="Entries" /></font>&nbsp;|<template:placeholder name="Entries" />
</html:template>
Die Verwendung sieht hierbei wie folgt aus:

Code: Alles auswählen

<?php
import ('extensions::arraypager::biz',
        'ArrayPagerManagerFabric'
        );
        
// Code

$oAPMF = $this->__getServiceObject ('extensions::arraypager::biz',
                                    'ArrayPagerManagerFabric'
                                    );
                                    
$oAPM = $oAPMF->getArrayPagerManager ('PagerSection');

unset ($oAPMF);

// Prüfen, ob der Pager bereits registriert ist oder die Seite
//  ohne Angabe einer Seitenzahl aufgerufen wurde
// Im zweiten Falle (keine Seitenzahl in der URL übergeben) wird
//  dabei davon ausgegangen, dass die Seite neu geöffnet wurde
//  und somit verhindert werden soll, dass nur ein Mal pro Session
//  die Daten geladen werden. Das kann zu Inkonsistenzen bei den
//  Daten führen. Alternativ kann man die Prüfung auch weglassen
//  und direkt jedes Mal die Daten komplett speichern, dann kommt
//  es nicht zu Inkonsistenzen.
if ($objectArrayPagerManager->checkPager ('PagerName') === FALSE
OR  $objectArrayPagerManager->checkPage ()             === FALSE
    )
{
  // Laden des Daten-Arrays
  $array = functionToLoadData ();

  // Registrieren des Daten-Arrays
  $oAPM->registerPager ('PagerName',
                        $array
                        );
}

// Laden des Pagers zur Ausgabe in einem PlaceHolder oder Ähnlichem
$stringPager = $oAPM->getPager ('PagerName');

// Laden der zur aktuellen Seite gehörenden Daten (wird bei
//  Funktionsaufruf anhand der Parameter mittels RequestHandler
//  ermittelt).
$array = $oAPM->loadEntries ('PagerName');

// Code
?>
Ich hoffe, dass ich damit einigen Leuten ein bisschen helfen konnte. Der Pager funktioniert sehr gut und hilft mir dabei auch noch die Datenbank-Abfragen zu minimieren (durch das Caching). Ich musste allerdings zwei Prüf-Methoden dazu bauen, um nicht umständlich im eigenen Code an die Informationen zu kommen und so habe ich gleich alles schön gekapselt. Wie man es letztendlich verwendet bleibt jedem Selbst überlassen. Man kann mit diesem Pager auch neben ganzen GORM-Listen einfach wie bisher IDs speichern und damit erst zur Laufzeit die Daten selbst abfragen, das ist halt Geschmackssache. Wichtig ist nur, dass man rechtzeitig alle Klasseninhalte geladen hat, bevor der SessionManager gestartet wird, da gespeicherte Objekte dann nicht richtig ent-serialisiert werden (die Klasse des zu ent-serialisierenden Objekts muss bei Session-Beginn bereits geladen sein).

Ich freue mich schon auf Feedback von euch.

Ich wünsche allerdings vorab schonmal ein schönes Fest, falls man sich erst hinterher schreiben sollte ;)
Dateianhänge
ArrayPager.zip
(8.01 KiB) 52-mal heruntergeladen
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

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

Re: [ArrayPager]

Beitrag von dr.e. » 21.12.2009, 21:05:19

Hallo Lutz,

ich habe zunächst den Code reviewed und sehe eine gute Umsetzung. Es wurden alle Feinheiten des APF beachtet und du nutzt zur Performance-Optimierung eine Factory. Fein! :geek:

Wenn du möchtest, nehme ich den Code in das APF-Release auf. Bedingung dafür wäre jedoch, dass du die Dokumentation ins Wiki unterhalb der Seite http://wiki.adventure-php-framework.org/de/Extensions überträgst. ;) Zur Hervorhebung des Codes kannst du den <source />-Tag nutzen. Dieser kennt im Attribut lang viele Sprachen (php,ini,xhtml, ...).
Viele Grüße,
Christian

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [ArrayPager]

Beitrag von MrNiceGuy » 21.12.2009, 21:11:20

Danke für das gute Feedback, allerdings ist die grobe Struktur ja auf deinen Mist gewachsen ;) Ich habe ja im Grunde eine Kopie des APF-Pagers einfach nur abgewandelt.

Du kannst das auch gerne mit aufnehmen, ich mache dann die Dokumentation fertig. Allerdings kann ich - auch bedingt durch das Projekt, an dem ich noch immer sitze - noch nicht genau sagen, wann ich das schaffe. Lass es sonst solange erstmal raus, bis ich die Doku fertig habe, OK?

BTW: Ich bin auch für Ergänzungen weiterhin offen ;)
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

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

Re: [ArrayPager]

Beitrag von dr.e. » 21.12.2009, 23:56:20

Hallo Lutz,

nur keinen Stress. Ich habe die Dateien ins SVN aufgenommen und du schreibst die Doku einfach bei Gelegenheit. Die aktuellen Files finden sich (nach ein paar kleinen Doku-Anpassungen) unter http://adventurephpfra.svn.sourceforge. ... rraypager/.
Viele Grüße,
Christian

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [ArrayPager]

Beitrag von MrNiceGuy » 22.12.2009, 23:47:22

Ich habe mal eine Dokumentation eingefügt. Du kannst sie ja mal gegenlesen und schauen, ob dir das so reicht oder ob bestimmte Dinge unverständlich sind (ich neige ja häufig dazu auch mal ausschweifend zu werden ;)).

LG
Lutz
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

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

Re: [ArrayPager]

Beitrag von dr.e. » 23.12.2009, 00:00:45

Hallo Lutz,

die Doku ist keinesfalls zu ausschweifend. Ich würde zur Abrundung noch
  • Eine kleine Einleitung (Was ist das? Was kann ich damit machen? Für welchen Anwendungsfall die Extension das gegenüber dem im APF enthaltenen Pager gedacht?).
  • Kleines Beispiel eines Gästebuchs(?).
  • Kurze Anleitung zur Anpassung der GUI-Templates.
einfügen. Grundsätzlich sollte jedoch der erste Punkt stark zum Verständnis beitragen, so dass die anderen Punkte eher unwichtig sind.
Viele Grüße,
Christian

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [ArrayPager]

Beitrag von MrNiceGuy » 23.12.2009, 09:33:26

Ich habe die Doku mal ein wenig angepasst. Ich habe eine kleine Einführung geschrieben und eine Kurzbeschreibung zu den Templates und wie diese verarbeitet werden. Grundsätzlich ist der Entwickler jedoch frei, was die Verwendung von Templates angeht und kann ja auch einen eigenen PageController programmieren.

Vielleicht gehe ich die Tage nochmal etwas näher auf die Thematik ein und beschreibe noch kurz, welche Templates und welche Variablen vorhanden sein müssen, wenn man den vorhandenen PageController nutzt aber ein eigenes Template nutzen möchte. Vielleicht fällt mir auch gleich schon etwas dazu ein.

Aber mal eine andere Frage: Ich habe gesehen, dass das eine Script noch eine ältere Version war bei der noch nicht geprüft wurde, ob die übergebenen Daten ein Array sind oder nicht. Ich habe entsprechend in der aktuellen Datei dann eine Version 0.2 aus der Methode gemacht, allerdings weiß ich nicht, wie ich die da jetzt ins SVN bekommen soll!?
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

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

Re: [ArrayPager]

Beitrag von dr.e. » 23.12.2009, 15:13:44

Hallo Lutz,

die Erweiterung gefällt mir gut. Vielleicht kannst du bei den relevanten Inhalten (z.B. Taglib <template:getstring />) noch einen Link auf die Doku einfügen.

Schick mir die neue Version einfach per PN oder hänge sie hier als ZIP an, ich spiele sie dann ins SVN ein. Solltest du Interesse haben, melde einfach bei Sourceforge einen Account an, dann füge ich dich als Entwickler hinzu und du kannst deine Sourcen selbst pflegen.
Viele Grüße,
Christian

Benutzeravatar
MrNiceGuy
Beiträge: 749
Registriert: 03.02.2009, 16:49:42
Wohnort: Nienburg / Weser

Re: [ArrayPager]

Beitrag von MrNiceGuy » 24.12.2009, 21:27:12

Das mache ich nach den Feiertagen. Angemeldet bin ich da schon und ich glaube du hast mich da auch schon eingefügt, nur habe ich bei der letzten Neuinstallation die SVN-Konfiguration nicht mitgespeichert und weiß zum Einen nicht mehr, wie das einzurichten war und zum Anderen weiß ich eh nicht genau, wie das mit dem SVN funktioniert. Ich werde diesbezüglich nochmal in meinen PNs schnuppern, da habe ich von dir irgendwo eine Kurzanleitung drin gehabt.

Stress dich also bitte nicht mit meinen Problemen und genieße die Feiertage :)
There are only 10 Types of people in the world:
Those who understand binary and those who don't.

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [ArrayPager]

Beitrag von dave » 31.03.2011, 20:08:52

Nabend,

die ArrayPager-Erweiterung klingt sehr interessant! Ich bin gerade dabei, das auch für mein Projekt umzusetzen. Der Eintrag im Wiki ist dafür auch sehr gut, habe auch noch einen kleinen Fehler dort verbessert.

Jedoch stosse ich bei der Ausgabe auf ein Problem. Ich habe es genau wie im Wiki gemacht:

Code: Alles auswählen

        // ArrayPagerManagerFabric instanziieren
        $oAPMF = $this->__getServiceObject('extensions::arraypager::biz', 'ArrayPagerManagerFabric');

        // ArrayPagerManager über Fabric laden
        $oAPM = $oAPMF->getArrayPagerManager('PagerSection');

        $DataArray = array('rosen','nelken','tulpen','blumen','gras','steine','pilze','lampen','keske','hasen','tiere','katzen','hund');

        // Registrieren eines Daten-Arrays zur Verwendung des Pagers
        $oAPM->registerPager('NameDesPagers', $DataArray);

        //Liefert die aktuelle Seite mit der angegebenen Anzahl Beiträgen je Seite zurück
        $DataList = $oAPM->loadEntries('NameDesPagers');

        print_r($DataList);

        // Lädt den Pager als fertige HTML-Ausgabe
        $HTMLOutput = $oAPM->getPager('NameDesPagers');
 
bei der letzten Codezeile stosse ich auf das Problem, folgende Exceptions werden mir geworfen:
Error-ID: d77bf33a897a6dc6034e18d388b4c382
Message: Undefined index: Pager.DesignNamespace
Number: 8
File: /is/htdocs/wp10589425_464WIA00JH/www/nahrungsmittelvergleich.de/apps/extensions/arraypager/biz/ArrayPagerManager.php
Line: 180
Und
Error-ID: dfb710921d307c09b8d1adf89b217e65
Message: Undefined index: Pager.DesignTemplate
Number: 8
File: /is/htdocs/wp10589425_464WIA00JH/www/nahrungsmittelvergleich.de/apps/extensions/arraypager/biz/ArrayPagerManager.php
Line: 181
Die Config ist vorhanden und verweist über den Namespace auf die Datei. Im Grunde ist alles da, trotzdem klappts nicht. Gibts da vllt. eine Änderung oder etwas in der Art?

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [ArrayPager]

Beitrag von Screeze » 31.03.2011, 20:18:06

Wie sieht die config aus, ich vermute da fehlen 2 werte

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [ArrayPager]

Beitrag von dave » 31.03.2011, 20:23:54

Code: Alles auswählen

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This is the main configuration file of the arraypager extension discussed under                  ;
; http://forum.adventure-php-framework.org/de/viewtopic.php?f=11&t=248                             ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[PagerSection]
Pager.DesignNamespace = "extensions::arraypager::pres::templates"
Pager.DesignTemplate = "arraypager"
Pager.Entries = "3" ; optional
Pager.ParameterPage = "page" ;optional
Pager.EntriesChangeable = "false" ;optional -- false|true
Pager.ParameterEntries = "entries" ;optional
Pager.EntriesPossible = "5|10|15" ;optional
Also meiner Meinung nach ist soweit alles chic. Den Pfad extensions/arraypager/pres/templates + Datei arraypager.html existiert auch auf dem Server ;)

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

Re: [ArrayPager]

Beitrag von dr.e. » 31.03.2011, 22:48:31

Hi dave,

der Pager muss mit $this->__getAndInitServiceObject() bezogen werden. Die init()-Methode initialisiert den Pager und dann ist auch die Config dort verfügbar.
Viele Grüße,
Christian

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [ArrayPager]

Beitrag von dave » 31.03.2011, 22:57:10

Ach, menno, da sind so gewisse Kleinigkeiten, die ich immer wieder vergesse :D. Ich passe das dann auch morgen gleich im Wiki an, dort ist auch noch so falsch drin.

Danke für den Hinweis!

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [ArrayPager]

Beitrag von Screeze » 31.03.2011, 23:05:11

Ach, menno, da sind so gewisse Kleinigkeiten, die ich immer wieder vergesse :D
Für sowas hatte ich mal ne liste mit standartfehlern, die ich wenn ich nixmehr weiter wusste erstmal der reihe nach durchgegangen bin, ob irgendwas in frage kommt ;P

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast