GIT repositories

Index page of all the GIT repositories that are clonable form this server via HTTPS. Übersichtsseite aller GIT-Repositories, die von diesem Server aus über git clone (HTTPS) erreichbar sind.

Services

A bunch of service scripts to convert, analyse and generate data. Ein paar Services zum Konvertieren, Analysieren und Generieren von Daten.

GNU octave web interface

A web interface for GNU Octave, which allows to run scientific calculations from netbooks, tables or smartphones. The interface provides a web form generator for Octave script parameters with pre-validation, automatic script list generation, as well presenting of output text, figures and files in a output HTML page. Ein Webinterface für GNU-Octave, mit dem wissenschaftliche Berechnungen von Netbooks, Tablets oder Smartphones aus durchgeführt werden können. Die Schnittstelle beinhaltet einen Formulargenerator für Octave-Scriptparameter, mit Einheiten und Einfabevalidierung. Textausgabe, Abbildungen und generierte Dateien werden abgefangen und in einer HTML-Seite dem Nutzer als Ergebnis zur Verfügung gestellt.

RSS 2.0 Rendering Klasse

RSS 2.0 rendering class

It can be so simple to generate RSS 2.0 feeds in PHP. The Rss2Feed class allows to render one or more channels in one RSS feed. All you have to do is to "feed" it with you data by overloading the onLoad() method. The results can be saved in a .rss file or directly sent to the Browser. The example show how:

Es kann recht einfach sein, in PHP RSS 2.0 Feeds zu erstellen - mit der Klasse Rss2Feed. Diese kann einen oder mehrere Feed-Channels in ein RSS-Feed rendern. Dazu muss sie lediglich durch Überladen der Methode onLoad()mit den verfügbaren Daten gefüttert werden. Die XML-Ausgabe kann entweder in einer .rss-Datei gespeichert oder direkt zum Browser gesendet werden. Das Beispiel zeigt, wie es geht:

Sample source code

Anwendungsbeispiel

<?php
include_once('swlib/swlib.class.php');
 
use sw\Rss2Feed;
use sw\OutputBuffer;
use sw\Tracer;
 
//
// Our class to customize the feed channel
//
class MyRss2Feed extends Rss2Feed {
 
  // That's the method we have to overload:
  protected function onLoad($identifier = '', $numOfItems = '') {
    // Instead of loading items from a database, we generate
    // a static array for this example:
    return array(
      'title' => 'CHANNEL TITLE',
      'description' => 'Channel description',
      'link' => '', // will be replaced with your $_SERVER[HTTP_HOST]
      'items' => array(
        array(
          'title' => 'Item 1 title',
          'description' => 'Item 1 description',
          'link' => 'http://item1.link/',
        ),
        array(
          'title' => 'Item 2 title &', // this will be escaped ("&")
          'description' => 'Item 2 description',
          'link' => 'http://item2.link/',
        ),
        array(
          'title' => 'Item 2 title with an "ü"',
          'description' => '', // No content
          'link' => '', // link will be replaced
        ),
      )
    );
  }
}
 
//
// Generate the feed with 100 items, only the default channel
//
try {
  $rss = new MyRss2Feed();
  $xml = $rss->renderFeed(array(), 100);
} catch (Exception $e) {
  $exception = $e;
}
 
// Script output
if (!isset($exception) && isset($_GET['rss'])) {
  // View the RSS in a reader
  OutputBuffer::purge();
  Tracer::disable();
  print $xml;
} else {
  // View the RSS XML code in the browser
  print '<html><body><pre>';
  print htmlspecialchars($xml);
  print '</pre></body></html>';
}

Output

Ausgabe

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  >
 <channel>
  <title>CHANNEL TITLE</title>
  <link>http://wp.localhost/</link>
  <description></description>
  <generator>swlib</generator>
  <ttl>60</ttl>
  <item>
   <title>Item 1 title</title>
   <description>Item 1 description</description>
   <link>http://item1.link/</link>
  </item>
  <item>
   <title><![CDATA[Item 2 title &]]></title>
   <description>Item 2 description</description>
   <link>http://item2.link/</link>
  </item>
  <item>
   <title><![CDATA[Item 2 title ü]]></title>
   <description></description>
   <link>http://wp.localhost/</link>
  </item>
 </channel>
</rss>

Class source code

Klassen-Quelltext

<?php
 
/**
 * Provides rendering one or more RSS channels into a RSS XML text.
 * @gpackage de.atwillys.sw.php.swLib
 * @author Stefan Wilhelm
 * @copyright Stefan Wilhelm, 2010
 * @license GPL
 * @version 1.0
 */
 
namespace sw;
 
class Rss2Feed {
 
  /**
   * That's how the channel specfication looks like:
   * @staticvar array
   */
  private static $dataTemplate = array(
      'title' => '', // Main title if the feed, should contain the website url
      'link' => '', // Link to the main web page of the channel
      'description' => '', // Text description of the feed
      'category' => '', // One or more category names
      'language' => '', // Channel language
      'copyright' => '', // Copyright information
      'generator' => 'swlib', // Feed generator
      'managingeditor' => '', // Email address of he managing editor
      'webMaster' => '', // Email address of the admin
      'pubDate' => '', // RFC822 time when the content was published
      'lastbuilddate' => '', // RFC822 time when the channel was modified
      'docs' => '', // RSS specification documentation link
      'cloud' => '', // Cloud service interface provider
      'ttl' => '60', // Time to live
      'image' => array(// Channel image:
          'url' => '', // Url to GIF, JPEG or PNG
          'title' => '', // Like alt tag in HTML
          'link' => '', // Page link (use link of the channel itself)
          'width' => '', // Optional width, mad 144
          'height' => '', // Optional height, mad 400
          'description' => '', // Optional like HTML title=""
      ),
      'rating' => '', //
      'textinput' => array(// Input text box:
          'title' => '', // The label of the Submit button in the text input area.
          'description' => '', // Explains the text input area
          'name' => '', // The name of the text object in the text input area
          'link' => ''            // The URL of the CGI script that processes text input requests
      ),
      'skiphours' => '', // Hours to skip update: int 0 to 23
      'skipdays' => '', // Days to skip update: Monday, Tuesday, Wednesday, ...
      'items' => array(), // THESE ARE THE ITEMS OF THE CHANNEL
  );
 
  /**
   * That's how the item specfication looks like:
   * @staticvar array
   */
  private static $itemTemplate = array(
      'title' => '', // Title of the Item
      'link' => '', // Link to the related HTML page
      'description' => '', // Text description
      'author' => '', // Author of the item
      'category' => '', // Item category
      'comments' => '', // URI to item comments
      'source' => '', // RSS channel where the content of this item is taken from
      'enclosure' => array(// Attached media data (array contents are XML attributes)
          'url' => '', // Link to the resource
          'type' => '', // MIME type
          'length' => ''          // Content length in bytes
      ),
      'guid' => '', // Global unique identifier
      'pubDate' => '', // RFC822 time when the item was published
  );
 
  /**
   * The text encoding of the feed
   * @var string
   */
  private $encoding = "UTF-8";
 
  /**
   * The channel data retrieved from the database or other sources
   * @var array
   */
  private $data = array();
 
  /**
   * Items, extracted form the data array returned by onLoad.
   * @var array
   */
  public $items = array();
 
  /**
   * Loads the data which are necessary to render an RSS feed.
   * OVERLOAD THIS FUNCTION TO CUSTOMIZE YOUR RSS CHANNELS.
   * Returns a reference to the result array, which must contain the
   * keys "title", "description" and "item"
   *
   * @param mixed $identifier
   * @param int $numOfItems
   * @return array
   */
  protected function onLoad($identifier='', $numOfItems=0) {
    return array();
  }
 
  /**
   * XML text escaping
   * @param string $text
   * @return string
   */
  private static function xmlEscape($text) {
    if (empty($text) || trim($text) == '') { // !empty for array()/null
      return '';
    } else if (!preg_match('/([^\x01-\x7f]|[&<>])/', $text)) {
      return $text;
    } if (strpos($text, ']]>') === false) {
      return "<![CDATA[$text]]>";
    } else {
      return str_replace(array('&', '"', "'", '<', '>'), array('&amp;', '&quot;', '&apos;', '&lt;', '&gt;'), $text);
    }
  }
 
  /**
   * Constructor
   * @param string $encoding
   */
  public function __construct($encoding="UTF-8") {
    $this->encoding = $encoding;
  }
 
  /**
   * Data access get
   * @param string $name
   * @return mixed
   */
  public function & __get($name) {
    $name = strtolower($name);
    return isset($this->data[$name]) ? $this->data[$name] : '';
  }
 
  /**
   * Data access set
   * @param string $name
   * @param mixed $value
   */
  public function __set($name, $value) {
    $name = strtolower($name);
    if (!isset($this->data[$name])) {
      throw new LException('No such RSS property to set');
    } else {
      $this->data[$name] = $value;
    }
  }
 
  /**
   * Loads the data using the overloadable onLoad() method.
   * @param mixed $identifier
   * @param int $numOfItems
   */
  public function load($identifier='', $numOfItems=0) {
    $this->items = null;
    $this->data = array_change_key_case(array_merge(self::$dataTemplate, $this->onLoad($identifier, $numOfItems)), CASE_LOWER);
    $this->items = &$this->data['items'];
    unset($this->data['items']);
 
    if ($this->title == '') {
      throw new LException('RSS channel title must be specified');
    }
 
    if (empty($this->link)) {
      $this->link = "http://{$_SERVER['HTTP_HOST']}/";
    }
 
    foreach ($this->items as $key => $item) {
      $this->items[$key] = array_change_key_case($item, CASE_LOWER);
      if (empty($item['title'])) {
        Tracer::trace("RSS item $key removed, no title");
        $this->items[$key] = false;
      } else if (empty($item['link'])) {
        Tracer::trace("RSS item $key ({$item['title']}) added channel link");
        $this->items[$key]['link'] = $this->link;
      }
    }
 
    if (count($this->items) == 0) {
      throw new LException('No RSS channel items defined');
    }
  }
 
  /**
   * Renders the channel
   * @return string
   */
  public function renderChannel($numOfItems=0) {
    $o = " <channel>\n";
 
    foreach ($this->data as $tag => $value) {
      if (!empty($value) || $tag == 'title' || $tag == 'description' || $tag == 'link') {
        if (!is_array($value)) {
          $o .= "  <$tag>" . self::xmlEscape($value) . "</$tag>\n";
        } else if (strlen(trim(implode('', $value), " \n\r\t")) > 0) {
          $o .= " <$tag>";
          foreach ($value as $itag => $ivalue) {
            $o .= "   <$itag>" . self::xmlEscape($ivalue) . "</$itag>\n";
          }
          $o .= " </$tag>";
        }
      }
    }
 
    $count = 0;
    foreach ($this->items as $item) {
      if ($numOfItems > 0 && ++$count > $numOfItems) {
        break;
      } else {
        $o .= "  <item>\n";
        foreach ($item as $tag => $value) {
          if (!is_array($value)) {
            $o .= "   <$tag>" . self::xmlEscape($value) . "</$tag>\n";
          } else if (strlen(trim(implode('', $value), " \n\r\t")) > 0) {
            if ($tag == 'enclosure') {
              $o .= "<enclosure url=\"{$value['url']}\" length=\"{$value['length']}\" type=\"{$value['type']}\" />";
            } else if (!empty($value) || $tag == 'title' || $tag == 'description' || $tag == 'link') {
              $o .= "  <$tag>";
              foreach ($value as $itag => $ivalue) {
                $o .= "    <$itag>" . self::xmlEscape($ivalue) . "</$itag>\n";
              }
              $o .= "  </$tag>\n";
            }
          }
        }
        $o .= "  </item>\n";
      }
    }
    $o .= " </channel>\n";
    return $o;
  }
 
  /**
   * Renders a list of channels in one feed
   * @param array $channelIdentifiers
   * @param int $numOfItems
   * @return string
   */
  public function renderFeed(array $channelIdentifiers=array(), $numOfItems=0) {
    $o = '<?xml version="1.0" encoding="' . $this->encoding . '" ?>'
            . "\n" . '<rss version="2.0"'
            . "\n" . '  xmlns:content="http://purl.org/rss/1.0/modules/content/"'
            . "\n" . '  xmlns:wfw="http://wellformedweb.org/CommentAPI/"'
            . "\n" . '  xmlns:dc="http://purl.org/dc/elements/1.1/"'
            . "\n" . '  xmlns:atom="http://www.w3.org/2005/Atom"'
            . "\n" . '  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"'
            . "\n" . '  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"'
            . "\n" . "  >\n";
    foreach ($channelIdentifiers as $identifier) {
      try {
        $this->load($identifier, $numOfItems);
        $o .= $this->renderChannel($numOfItems);
      } catch (\Exception $e) {
        Tracer::traceLException($e);
      }
    }
    $o .= '</rss>';
    return $o;
  }
 
}