Whitelabel Shoplösung bei sbuy.ch

[Trigami-Review]

Whitelabel? Die Idee…

AffiliateViele Website- und Blogbetreuer benutzen sogenannte Affiliatesysteme. Dabei werden Produkte verkauft (direkt oder beispielsweise in Blogbeiträge eingestreut) und dafür Provisionen eingestrichen. Im Grossen und Ganzen ist der Aufwand für den Websitebetreiber gering, da oftmals der gesamte Verkauf an sich und die Abrechnung über den Anbieter geschieht. Soundmedia AG geht nun einen Schritt weiter und bietet die Möglichkeit, einen ganzen Shop selber zu erstellen. Dabei können Teile des Designs, Produktauswahl, etc selbst bestimmt werden.

Die Vision

Meine Vision: Eine neue Art Hobby und lukratives Freizeitvergnügen. Man erstellt sich Shops und versucht, diese zu promoten. Alle „hässlichen“ Details wie Lagerhaltung, Abrechnungen, Inkasso, Versand, etc werden vom Whitelabelanbieter übernommen und man kann sich voll und ganz auf die Marketingmassnahmen seines Shops konzentrieren und sich als Manager fühlen. Das wäre spannend, würde Einblicke ins Marketing geben und wäre erst noch rentabel für erfolgreiche Shopmacher.

Ich möchte am Schluss feststellen, ob diese Vision erreicht werden kann oder nicht…

Die Realisierung

sbuy.ch

sbuy.ch wird unterhalten von der Soundmedia AG, die aus der ehemaligen B&H Sound Media Versand AG hervorgegangen ist. Ich mag mich noch gut an die Prospekte der B&H erinnern 🙂 .

Das Erstellen eines eigenen Shops ist absolut gratis und es stehen über eine Million Produkte zur Verfügung, die angeboten werden können. Diese sind vorallem aus den Bereichen Musik, Film, Games und Software, Bücher und Lifestyle. Die Provisionen bewegen sich – je nach Umsatz – zwischen 8% bis 10%.
Weiterlesen

flughexe.ch – Finde den günstigsten Flug

Dies ist ein von trigami vermittelter bezahlter Eintrag Hinweis: Dies ist ein von trigami vermittelter bezahlter Eintrag.

Einen Flug hexen?

FlughexeEigentlich ist das Fliegen ja kein Spass. Man sitzt da, dicht eingezwängt zwischen labernden oder schnarchenden Nachbarn, deren Menüplan an ihrer Transpiration erkennbar ist, das Handgepäck sollte streichholzschachtelgrösse nicht überschreiten, da es sonst nimmer in die Ablage passt, zum Essen gibt es feuchten Karton mit Sägespänen und der dringend benötigte Alkohol wird einem vor der Nase hin und her getragen. Ganz zu schweigen von den Erstickungsanfällen, weil das Rauchen verboten ist wenn man nur schon an einen Flughafen denkt, die Flieger immer Verspätung haben oder gar nicht mehr fliegen (wie schon mit EasyJet erlebt) und der Kaffee den Namen nicht verdient hat. (BTW: Auf meinen ersten Flügen habe ich noch geraucht, jaaa, im Flugzeug drin! Und Essen gabs auch, mit Wein!!! Damals war die Welt noch eine Scheibe, aber durchaus in Ordnung 🙂 ).

Nundenn, Laufen ist leider immer noch mühsamer, und so will ich wenigstens so wenig wie möglich für diese Tortur bezahlen. Da gibts nun verschiedene Möglichkeiten:

  • Ich gehe ins Reisebüro. Nachteil: ich bezahle unter Umständen zusätzlich die Beratung und sie haben Öffnungszeiten.
  • Ich checke alle Fluggesellschaften durch die es gibt. Nachteil: Das gibt mächtig zu tun.
  • Ich bediene mich eines Preisvergleichers. Und genau hier kommt die Flughexe ins Spiel.

Oberfläche und Bedienung

Die Website http://www.flughexe.ch kommt im modernen Web-2.0 Design daher: Klar, mit knalligen Farben (nur die Web 2.0 typischen Gradienten fehlen) und mit runden Ecken. Mir gefällt dieses Schnörkellose sehr. Die zentrale Sache der Website (das Suchen nach Flügen) ist zentral in der Mitte. Sehr diskret ist etwas Werbung auf der Seite verteilt.

Flughexe-Screenshot

Die Bedienung ist sehr einfach: Eingeben was man wünscht, Formular abschicken, kurz warten und schwupps erscheinen die Resultate, aufsteigend nach Preisen geordnet, mit Zwischenstopps, etc. Die Suche geht erfreulich schnell vonstatten! Einige andere Flugsuchen – die sich mitunter nur mit einer Airline beschäftigen müssen – scheinen zuerst jemanden aufs Rollfeld zum Nachfragen zu schicken, der dann die Flüge von Hand eintippt. Bei den Resultaten gibt es ein Link zu den jeweiligen Partnern, von wo aus dann der Flug gebucht werden kann.

Es ist möglich, sich einen Account zu erstellen. Dieser bietet aber keine weitere Vorteile als einen Newsletter. Naja, ich bekomm ja so extrem wenig Mails…

Technik

Hier der gefürchtete Teil der Rezension 🙂 . Natürlich habe ich wieder was herumzumaulen.

Zum Einen wieder mal das Logo oben links. An sich sollte es zurück auf die Homepage führen, das hat sich so eingebürgert. Flughexe gibt es nun in zwei Versionen: flughexe.ch mit Preisen in Schweizerfranken und flughexe.com in Euro. Ein Klick auf das Logo führt nun immer auf die Euroversion, was sehr verwirrend sein kann (ok, ist so beschriftet, aber trotzdem…).

Etwas hässlicher ist, dass man immer ein Rückflugdatum angeben muss, das hinter dem Abflugdatum liegt, auch wenn man nur den Hinflug anzeigen lassen will. Sonst wird man ziemlich bestimmt zurecht gewiesen, inklusive Ausrufezeichen!

Wenn man auf Google angewiesen ist, dann sollte man nett mit Google sein. Diese Seite bietet da noch einiges an Optimierungspotential:

  • Der Titel ist mit Schlüsselwörtern gefüllt. Das sieht beim Erstellen eines Lesezeichens hässlich aus und interessiert Google schon lange nimmer so.
  • Die Schlüsselwörter werden im keywords Metatag wiederholt. Ok, aber in description und abstract gehören sie nicht auch noch! Das kann ganz übel aussehen bei den Excerpts in den Suchresultaten. Wer klickt denn auf so einen Eintrag (so gefunden bei Google):
    Flughexe bei Google
  • Die Site hat 26 HTML Fehler. Beim CSS sind es nur 4 Ungereimtheiten. Das mag Google nicht und das ist auch nicht zukunftsgerichtet, wenn man an die mobilen Geräte denkt.
  • Weitere SEO-Aktivitäten (Social Bookmarking, Alexa-Ranking, …) wurden anscheinend nicht durchgeführt.

Offene Partnersache?

Es wäre interessant wenn irgendwo offen und transparent aufgeführt würde, welche Fluggesellschaften berücksichtigt werden. Ich habe diese Information nirgends auf der Seite auftreiben können.

Zum Buchen der Flüge scheint als einziger Partner LTURfly.com aufgeführt. Sind denn alle Flüge dort auch auffindbar? Was ist der Mehrwert der Flughexe (ausser dem schöneren Design)? Ganz unten ist auch noch ein Link auf Billig-Reise platziert. Diese Site bietet ebenfalls eine Suche nach Flügen aus der Schweiz an, allerdings viel weniger komfortabel als das Hexchen. Aber wie ist da der Zusammenhang? Das wirkt auf mich etwas undurchsichtig.

Verbesserungsvorschläge

Neben den Fehlern und den Unklarheiten hätte ich einen ganz klaren Wunsch: Ich will beispielsweise von der Schweiz aus nach Amsterdam. Jetzt muss ich alle Schweizerflughäfen durchprobieren, denn der Preisunterschied kann enorm sein! Wenn es nun auch am Zielort drei Flughäfen gibt und ich jeweils Zürich und Basel ausprobieren muss, dann ergibt das sechs Suchanfragen. Es wäre ein echter Mehrwert, wenn das irgendwie automatisiert werden könnte.

Vielleicht könnte man auch noch den Account ein bisschen aufpeppen und die schon gewählten Destinationen einfacher erreichbar machen oder so ähnlich. Das würde die Kunden auch mehr binden.

Fazit

Die Flughexe sucht günstige Flüge, und das macht sie gut. Die Seite gefällt und ist sehr benutzerfreundlich. Etwas Transparenz und ein paar Goodies würden sie noch mehr aus der Masse herausstechen lassen.

Voting Extrem: Netvoting.com

Dies ist ein von trigami vermittelter bezahlter Eintrag Hinweis: Dies ist ein von trigami vermittelter bezahlter Eintrag.

Ergänzung Juni 2009: Netvoting ist vom Netz… Ohne kommentar und nic…

Die Kampagne

Netvoting Diese Kampagne hat sehr geheimnisvoll begonnen. Es wurden Betatester für eine Web 2.0 Plattform gesucht, ohne genauere Auskünfte. Mit etwas Verspätung haben wir akzeptierten Tester einen Login erhalten und der Schleier um http://www.netvoting.com/ (Netvoting) wurde gelüftet. Während der ganzen Testdauer wurden stetig Dinge verbessert, dieser Bericht wird also eine Art Momentaufnahme darstellen.

Was ist Netvoting?

Netvoting ermöglicht es sogenannte Votings als Multiplechoicefragen zu erfassen und einer Kategorie (Lifestyle und Trends, Luxus, Musik, Erotik, …) zuzuordnen. Neben dem Erstellen eigener Votings können die Abstimmungen der anderen Members angesehen werden und selbstverständlich kann man auch daran teilnehmen. Es ist unglaublich auf was für Abstimmungsideen die User schon jetzt im Betabetrieb so kommen: Da wird gefragt, ob Burschenschaften rechts und ob Comics Kunst sind, ob der Po das schönste Körperteil einer Frau ist und ob man sich auf Weihnachten freut.

Was noch nicht funzt ist das Deaktivieren und Editieren von Votings. Vor allem für Falsschreibkönige die ständig die Wechselstaben verbuchseln wie ich einer bin ist das eher peinlich…

Technisches

Erstellen des Votings

Das Erstellen eines Votings geht erfreulich einfach von der Hand: Frage und Antworten eingeben, Einstellungen machen, taggen und kategorisieren und fertig (Betatesterkommenar: Es hat auf dieser Seite mindestens einen Schreibfehler: „eröffentlichen“ (ok, ich bin nicht so richtig qualifiziert um an Schreibfehlern herumzumäkeln 🙂 )).

Votings erstellen

Von diesem Zeitpunkt an ist das Voting auf Netvoting publiziert…

Publizieren auf der eigenen Seite

Mit einem Klick kann das Voting auf Plattformen wie iGoogle, Pageflakes, blogger.de, etc veröffentlicht werden. Vor dem Veröffentlichen kann optional ein Style ausgewählt oder mittels CSS selber definiert werden. Das ist eine gute Idee, leider funktioniert das noch nicht… Zum konkreten Einbetten gibt es 3 Möglichkeiten:

JavaScript (ja wo issn mein Style?):
Flash:

Oder ein Permalink: http://www.netvoting.com/de/welche-themen-interessieren-euch-am-meisten-in-einem-blog-2007

Ebenfalls kann/könnte man Widgets einbinden. Widgets beinhalten entweder konkret ausgewählte Votings oder wählen an Hand von verschiedenen Kriterien dynamisch aus. Leider sieht man an Hand dessen, dass man hier nichts sieht, dass es noch nicht funktioniert. Auch können hier keine Styles ausgewählt werden..(?)


Oberhalb sollte das Widget erscheinen…

Was auch noch nicht so richtig klappt ist die Erkennung von Mehrfachvotern, zumindest nicht bei Cookies. Hier kann man also fröhlich Schummeln…

Resultate

Die Resultate werden zusammengefasst dargestellt und einzeln aufgeteilt nach Registrierung, Geschlecht, Region und Altersstruktur. Leider können diese nicht kommasepariert exportiert werden und man ist für weitere Auswertungen aufs Abschreiben angewiesen. Eine geniale Idee ist der Resultate-RSS-Feed. Damit ist man sehr zeitnah über Fortgang des Votings informiert.

Netvoting Resultate

Community

Um die Votings herum wurde eine Community aufgebaut. Das ist gar nicht so abstrus wie es auf den ersten Blick klingt. Das Ganze beginnt mit dem sehr ausführlichen Profil. Darin werden Freunde verwaltet, Besucher des Profils angezeigt und das Eingeben von ziemlich vielen persönlichen Daten ist möglich. Ein Gästebuch gibts noch dazu. In Gruppen können sich Gleichgesinnte zusammenfinden für die dann eine Art Gruppenblog zur Verfügung steht.

Zusätzlich gibt es ein Ranking mit Awards. Dabei werden Votings, Kommentare, etc berücksichtigt.

Beim Anschauen anderer Profile liegen Licht und Schatten sehr nahe beieinander: Man sieht die Anzahl übereinstimmender Votings mit der Person. Hier wäre eine Art „Nachbarschaftsfunktion“ schön, welche die Mitglieder mit den meisten Übereinstimmungen auflistet. Weniger schön ist es, dass man hier genauen Einblick erhält was die Person abgestimmt hat! Ja gehts denn noch? Und ich merk das erst nachdem ich die Erotikkategorie durchgestimmt habe? Upps, *blush*.

Fazit

Eine schöne Sache! Ich mag Tools die sich auf etwas konzentrieren und dies richtig tun. Vielleicht werde ich in Zukunft hier öfters kleine Votings platzieren, aber erst wenn alles funktioniert.

PHP-UWA Widget Library

[lang_de]Update Jan 2011: Die PHP-UWA-Library wurde völlig überarbeitet und funktioniert nun mit der aktuellen IFrame-Methode. Das Prinzip bleibt das Gleiche, die Aufrufe sind leicht anders: Projekt auf oncode.info.[/lang_de]
[lang_en]Update Jan 2011: The PHP-Update library has been completely rewritten and does now support the current IFrame-Method. The principles are still the same, but the API has changed quite a bit: Projekt auf oncode.info.[/lang_en]
[lang_de]

Widgets und Web 2.0

Universal Widget ArchitectureWidgets sind kleine Miniapplikationen, die übersichtlich wichtige Daten anzeigen oder kleinere Funktionen ausführen. Es gibt sie für Windows Vista, Mac, iPhone sowie Webbasiert für iGoogle, Yahoo!, Netvibes und so weiter und so fort. Um die Entwicklung zu forcieren, stellt nun Netvibes ein Rahmenwerk vor, das die Entwicklung von Widgets für alle diese Plattformen vereinfachen soll: Die Universal Widget Architecture. Die Widgets, die nach diesem Standard programmiert sind, sollen unter allen diesen Plattformen laufen…[/lang_de]
[lang_en]

Widgets and Web 2.0

Universal Widget ArchitectureWidgets are little miniapplications which show data in a clearly arranged way or perform a more or less simple task for the user. Widgets are present on Windows Vista, Mac, iPhone and also in a webbased form for iGoogle, Yahoo!, Netvibes and many other portals. To give a boost to widget development, Netvibes presented a new framework which shall facilate the coding of widgets. The child is called Universal Widget Architecture. Widgets coded with the help of this framework should work on all the mentioned plattforms.[/lang_en]

[lang_de]

UWA Standard

Ein Widget im UWA-Standard ist ein XML-Dokument. Es enthält Metadaten, Einstellungen und den aktiven Teil, geschrieben in Javascript. Besonders die Einstellungen sind interessant, denn über diese können widgetspezifische Parameter angepasst werden. Einige Toolfunktionen runden das UWA-Paket ab.[/lang_de]
[lang_en]

UWA Standard

A widged, coded with UWA is basically a XML-Dokument. It contains metadata, settings and the active part, written in Javascript. Especially the Preferences are of interest, because they are dynamic and allow widgetspecific settings. There are also some convenience-functions in the UWA-library.[/lang_en]

[lang_de]Die UWA-Spezifikation hat ihre eigene Homepage und ist gut dokumentiert. Es gibt Beispiele, ein Code-Skelett mit Erklärung, ein Schritt-für-Schritt Tutorial, ein Forum und sogar ein Cheat-Sheet. Der Einstieg wird einem wirklich so einfach wie möglich gemacht.[/lang_de]
[lang_en]The UWA specification has its own homepage and is very well documented. There are examples, a code-skeleton with explanations, a step-by-step tutorial, a forum and even a cheat-sheet. The start is very easy with such a lot of documentation.[/lang_en]

[lang_de]

Widget Repository

Fertige Widgets können im Widget Repository (Ecosystem) der Öffentlichkeit zur Verfügung gestellt werden. Von diesem System aus können die Widgets zu den verschiedenen Plattformen mittels Mausklick hinzugefügt werden. Im Repository hat es auch noch Widgets, die nach dem veralteten Mini-API Standard funktionieren, diese werden jedoch (hoffentlich) bald verschwinden.[/lang_de]
[lang_en]

Widget Repository

Finished and released widgets can be made available for the public and published in the Widget Repository (Ecosystem). Widgets ion this website can be added to the different platforms with a single (or double) click). There are some widgets in the repository which are coded in the deprecated Mini-API standard, but these will dissappear soon (hopefully).[/lang_en]

[lang_de]

Implementationen

Das klingt echt faszinierend und schreit danach, genutzt zu werden. Widgets selbst werde ich später implementieren, als erstes wollte ich sie wirklich für eigene Projekte nutzbar machen. Dafür habe ich eine kleine PHP- Klasse entworfen und sie grosskotzig PHP-UWA Widget Library genannt. Mit ihr ist die Handhabung von Widgets ziemlich einfach. Etwas ambitionierter ist das Parsing der widgetabhängigen Einstellungen.[/lang_de]
[lang_en]

Implementations

That sounded fascinating and must have a use somewhere… I will implement some widgets later, I needed to make these widgets usable in our own projects first. So I wrote a little PHP-class which I called pretentious PHP-UWA Widget Library.Handling widged should be easy, using this class. A little bit more ambitious is the handling of widget dependend preferences.[/lang_en]

[lang_de]Ein Minimalbeispiel ist im Download-Paket dabei und kann auch online aufgerufen werden.[/lang_de]
[lang_en]A minimal example is included in the download-package and can also be checked online.[/lang_en]

PHP-UWA Widget Library Example

[lang_de]Ein Widget anzuzeigen geht recht fix:[/lang_de]
[lang_en]Displaying a widget should be straight forward:[/lang_en]

<?php
require_once('uwawidget.php');
$uwawidget=new uwawidget('http://www.netvibes.com/api/uwa/examples/digg.xhtml');
echo $uwawidget->getWidgetHTML();
?>

[lang_de]Informationen über das Widget (sobald die URL angegeben wurde) geben die folgenden zwei Methoden:[/lang_de]
[lang_en]There are two classmembers which can give more information about the widget:[/lang_en]

getMetaData()
[lang_de]Metadaten wie Autor, Keywords, Beschreibung, … Siehe Doku.[/lang_de][lang_en]Metadaten like author, keywörds, description, … See the docu.[/lang_en]
getAdditionalData()
[lang_de]Zusätzliche Daten wie Icon, Stylesheet, …[/lang_de][lang_en]Additional info like icons, stylesheets, …[/lang_en]

[lang_de]Grundsätzlich gibt folgende Einstellungsbereiche:[/lang_de][lang_en]Basically, there are the following sections for settings:[/lang_en]

general
[lang_de]Die URL zum Widget.[/lang_de][lang_en]The widgets URL.[/lang_en]
configuration
[lang_de]Anzeigeparameter, die in der Doku beschrieben sind.[/lang_de][lang_en]Displayparameters, which described in the docs.[/lang_en]
preferences
[lang_de]Widgetabhängige Einstellungen, die ebenfalls in der Doku erwähnt sind.[/lang_de][lang_en]Widget dependent preferences, also mentioned in the docs[/lang_en]

[lang_de]Zu allen diesen Einstellungen gibt es folgende Methoden:[/lang_de][lang_en]For all these settings, there are the following classmembers:[/lang_en]

[lang_de]Setters und Getters[/lang_de][lang_en]Setters and Getters[/lang_en]
setModuleUrl(), setConfiguration(), setPreferences()
getModuleUrl(), getConfiguration(), getPreferences()
getSettingsFormData($section)
[lang_de]Gibt die Settings in einem lesefreundlichen Array wieder, aus welchem ziemlich einfach ein Form generiert werden kann. $section ist dabei "general", "configuration" oder "preferences"[/lang_de][lang_en]Returns the settings in a friendly array, from which a form can be generated. $section can be "general", "configuration" or "preferences"[/lang_en]
getSettingsHTML($section)
[lang_de]Gibt die Settings in Array der Form "Label" => "HTML" zurück. $section ist dabei "general", "configuration" oder "preferences"[/lang_de][lang_en]Returns the settings in an array with the format "Label" => "HTML". $section can be "general", "configuration" or "preferences"[/lang_en]

[lang_de]Zum Test habe ich Moodleblock erstellt, welcher nun die Darstellung von UWA-Widgets innerhalb des LMS erlaubt. Heyo, WordPress, Xoops, etc-Coderz, wie wärs bei Euch mit einer UWA Integration???[lang_de]
[lang_en]For a test, I coded a Moodle block, which allows to use UWA Widgets inside the LMS. Heyo, WordPress, Xoops, etc-Coderz, how about an integration of the Widgets in your system???[/lang_en]

[lang_de]Beispiele vom Moodleblock:[lang_de]
[lang_en]Examples from the Moodle block:[/lang_en]

Moodle UWA Calculator Moodle UWA Converter Moodle UWA Translator
Moodle UWA Google Notes Moodle UWA Spider Moodle UWA ToDo
[lang_de]Die Konfiguration unter Moodle:[/lang_de][lang_en]The configuration in Moodle:[/lang_en]
Widget settings in Moodle

[lang_de]

Ui, fast…

…wäre ich schneller als das aktuelle c’t gewesen, welches eine gute aber knappe Einführung in UWA-Widgets enthält.[/lang_de]
[lang_en]

Uh, almost…

…I was almost faster than the german computer magazine c’t which has a short bit good introduction into UWA-Widgets.[/lang_en]

Drupal mit neuen Google AdSense Werbeblöcken (Serverbasiert)

Neues AdSense


(Affilliate Link 🙂 ) sind neuerdings Serverbasiert. Das heisst: Aussehen, Inhalt, etc kann grösstenteils von der AdSense-Seite aus gemanaged und muss nicht mehr mühsam von Hand auf jeder Seite eingepflegt, geftpt und gecheckt werden. Das geniale Drupal AdSense Modul beherrscht diese neue Variante leider (noch) nicht von Haus aus. Mit einem kleinen Patch geht das aber.

Vorgehen

  1. Die Datei adsense.module mit diesem Patch so patchen, wie in diesem Beitrag beschrieben.
  2. Auf der Google AdSense Seite AdSense-Setup → Anzeigen Verwalten aufrufen und eine neue Anzeige designen.
  3. Den Code anzeigen lassen und die Slot-Nummer notieren. Es sollte etwas sein wie 2666876213.
  4. In Dupal als Administrator Administer → Site configuration → Google AdSense aufrufen und Custom Channels aufklappen.
  5. Die Slotnummer in einen Channel schreiben.
  6. Diesen Channel beim Block für die Anzeige einsetzen.
  7. Warten… Und sich freuen…

Erstellen eines Timers in Xoops

Xoops ist ein geniales CMS, auch wenn es in letzter Zeit durch administrative Querelen nicht sehr gute Schlagzeilen gemacht hat. Wir benutzen es in einer erweiterten Version als Intranet.

Nun braucht ein Modul plötzlich unendlich lange um sich darzustellen. Das hindert unseren rasanten Arbeitsfluss und darum muss darum korrigiert werden. Statt rumzufrickeln lohnt es sich, die Sache seriös anzugehen.

Xoops bietet eine sehr gute Debugfunktion an: Adminsitration → Systemeinstellungen → Voreinstellungen → Allgemeine Einstellungen → Debug-Modus kann auf PHP-Debug gesetzt werden. Danach werden unten an der Seite viele Infos dargestellt, unter Anderem SQL-Befehle und Timer.

Xoops Debug

Genau solche Timer kann man selber einfach erstellen. Zuerst muss der XoopsLogger eingebunden werden:

include_once(XOOPS_ROOT_PATH . '/class/logger.php');

Um einen Timer zu starten:

$xoopsLogger->startTime( 'absence_count_query' );

Um ihn wieder zu stoppen:

$xoopsLogger->stopTime( 'absence_count_query' );

Diese Timer wird nun – wie oben ersichtlich – wunderschön in die Debugfunktion eingereiht.

Moodle Block Resource-Download

Der Moodle Resource Download Block

Moodle Resource Download Block Auf vielfachen Schülerwunsch hin habe ich einen Block für unser Learning Management System Moodle codiert: Den Resource Download Block. Er erlaubt den Download aller Kursdateien und Verzeichnisse in einem ZIP-Archiv. Dieses Zip-Archiv wird wie im Beitrag Zipdateien on-the-fly erstellen mit PHP dynamisch erstellt, da (in der Theorie) jeder Lernende eine andere Kursansicht haben kann.

Einen Block erstellen ist relativ einfach, wenn man dem Block Howto folgt, aber der Teufel liegt wie immer im Detail.

Configwerte

Jeder Block kann verschiedene Konfigurationswerte erfragen und erhalten. Diese unterscheiden sich aber, ob der Block global (pinned, sticky) ist, in welchem er nur von einem Ort aus konfiguriert wird oder ob er den individuellen Kursen hinzugefügt wurde, wobei dann jede Instanz ihre eigene Konfiguration hat. Ich habe mich für den zweiten Weg entschieden.

Um die Konfigurationsvariablen mit einem Defaultwert zu versehen, muss man sich in der instance_config_print() Methode darum kümmern:

if (!isset ($this->config)) {
    // ... teacher has not yet configured the block, let's put some default values here to explain things
    $this->config->exclusionregexp= block_downloader_default_exclusionregexp();
    $this->config->compression= block_downloader_default_compression();
    $this->config->maxsize= block_downloader_default_maxsize();
}

Die Datei, die das Zip zusammenstellt ist mehr oder weniger ausserhalb von Moodle, da sie nicht „als Block“ erscheinen kann. Um da an die Konfigurationsdaten zu kommen, muss man etwas mehr Aufwand treiben. Sie befinden sich base64 codiert in den Tabellen block_instance respektive blocks_pinned für globale Blocks. courseid und instanceid werden dabei vom Link im Block übergeben.

<?php

/**
 * Create the zip on the fly and push it to the browser.
 */


require_once ('../../config.php');
require_once ($CFG->dirroot . '/blocks/downloader/lib/archive.php');
require_once ($CFG->dirroot . '/blocks/downloader/lib/downloadlib.php');
require_once ($CFG->dirroot . '/lib/filelib.php');
require_once ($CFG->dirroot . '/lib/moodlelib.php');
require_once ($CFG->dirroot . '/blocks/downloader/lib/downloadlib.php');

$courseid= required_param('courseid', PARAM_INT); // Course identification
$instanceid= required_param('instanceid', PARAM_INT); // Instance of the block

// Securitycheck
[SNIP]

// Get Config Data
$where= "pagetype = 'course-view' AND visible = 1 AND id=" . addslashes($instanceid);

// Instance?
$blockarr= get_records_select('block_instance', $where . " AND pageid=" . addslashes($courseid));

// Maybe pinned? In this case we have no courseid
if (!$blockarr) {
    $blockarr= get_records_select('block_pinned', $where);
}

if (!$blockarr) {
    error("cannot find block with: " . $where . " AND pageid=" . addslashes($courseid));
    exit ();
}

// Take the first result
$block= array_pop($blockarr);

$configdata= unserialize(base64_decode($block->configdata));

print_r($configdata);

[...]

Dateien pro Kurs abholen

Das Zusammenstellen aller Pfade für Dateien, die ein Benutzer sieht und auf die er Zugriff hat ist echt mühsam. Ich wünsche mir hier ein Bisschen den Servicegedanken: Beispielsweise würde man viel Zeit sparen, wenn der Entwickler mit dem entsprechenden Wissen Funktionen wie can_read($userid, $resourceid) implementieren würde. Zusätzlich wäre man unabhängig vom verwendeten Absicherungsschema. Ich werde das zukünftig in meinen Programmen berücksichtigen.

Reaktionen

Die Community hat – wie meistens bei Moodle – sehr nett auf die Veröffentlichung reagiert. Zwei Tage nach Version 1.0.0 habe ich schon eine Slovakische Übersetzung und diverse Hinweise auf Bugs erhalten.

Installation von Drupal ohne „CREATE TEMPORARY TABLE“ Rechte unter MySQL

Problem

Drupal[lang_de]Einige Hoster geben – wahrscheinlich wegen des momentanen Vollmondes – das MySQL Recht CREATE TEMPORARY TABLES nicht an ihre Kunden. Drupal möchte das leider und so muss man es umgehen 🙁 …

Bei der Installation beispielsweise wird gemeldet:[/lang_de]
[lang_en]
Some hosting providers do not grant the MySQL-userright CREATE TEMPORARY TABLES to their customers. Maybe because it’s full moon at the moment and everyone seems a bit crazy. But a href=“http://drupal.org/“>Drupal really wants this right and so a workaround is needed 🙁 …

The error during the installation could be something like this:[/lang_en]

user warning: Access denied for user: 'drupal@%' to database 'drupal' query: CREATE
TEMPORARY TABLE missing_nids SELECT n.nid, n.created, n.uid FROM node n LEFT
JOIN node_comment_statistics c ON n.nid = c.nid WHERE c.comment_count IS NULL in
/var/websites/drupal/includes/database.mysql.inc on line 167.

[lang_de]

Eine Art Lösung

Ich habe für Drupal 5.2 einen Patch erstellt der das Problem lösen sollte. CREATE TEMPORARY TABLES ist in Drupal vorbildlich in eine einzige Funktion db_query_temporary in der Datei includes/database.mysql.inc ausgelagert. Grundsätzlich erstellt dieser Patch statt einer temporären eine richtige Tabelle, deren Erstellungsdatum in einer weiteren Tabelle mit Namen temporary_table gespeichert wird. cron.php entfernt diese dann regelmässig. Sollte die Tabelle schon existieren bei der Erstellung, wird sie vorgängig gelöscht.

Das Ganze funktioniert nur für MySQL und MySQLI und bedeutet einen enormen Geschwindigkeitsverlust. Ich habe den Patch nur bei einer low-traffic Site getestet und weiss nicht, ob es vielleicht noch Race-Conditions geben könnte. Benutzung also auf eigene Gefahr.[/lang_de]
[lang_en]

Kind of a Solution

I have written a patch for Drupal 5.2 which should kinda solve the problem. In Drupal, CREATE TEMPORARY TABLES is only used in the db_query_temporary function, found in the file includes/database.mysql.inc, which is a very clean progamming style! Basically, this patch creates a real table instead of a temporary one. The name and the creationdate is stored in an extra table called temporary_table. The cron.php removes these tables on a regular base. If the table already exists, it is dropped.

This patch only works for MySQL and MySQLI and may be a performance loss. I have tested this patch only on a low traffic site and I do not know if there are race conditions. Use it on your own risk…

Addendum

Another solution has been posted at Drupal.org.

[/lang_en]

[lang_en]Here it is: Patch to use Drupal without the CREATE TEMPORARY TABLES.

To apply it, change into the Drupal base directory and issue patch -p0<drupalwotemptables.patch on the commandline.[/lang_en]
[lang_de]Und hier ist er: Patch für Drupal ohne CREATE TEMPORARY TABLES.

Um ihn anzuwenden ins Basisverzeichnis wechseln und patch -p0<drupalwotemptables.patch ausführen.

Nachschlag

Eine weitere Lösung wurde bei Drupal geposted.
[/lang_de]

CMS? Erschlag mich!

Der Auftrag

desperateIch möchte für die Website www.oncode.info ein schnuggeliges opensource CMS, das mir ermöglicht, meinen abgesonderten Code irgendwie halbwegs schön zu präsentieren und zum Download anzubieten. Als besondere Extremhürde würde ich zusätzlich gerne den RSS-Feed dieses Blogs anzeigen und irgendein schönes Design übernehmen, da ich die Fähigkeit habe, alles hässlich aussehen zu lassen wenn ich es selbst in die Hand nehme. In Java hingegen möcht ichs nicht, da Tomcat mich nicht mag…

Die Ausführung

Das kann doch nicht so schwer sein! hat sichs gedacht, obwohl mans doch besser weiss. Xoops kenne ich schon und mit Typo3 habe ich auch schon Erfahrungen gesammelt, was Neues sollts schon sein irgendwie. Bei opensourcecms kann man verschiedene OSS CMS ausprobieren (genial! Mit Adminfrontend!) und bei cmsmatrix können ebendiese verglichen werden. Es scheinen also auch schon andere arme Kerle mit diesem Problem konfrontiert worden zu sein. Obwohl Joomla! unterschiedlich gute Schlagzeilen macht, hat es auf den ersten Blick doch gut und vielseitig ausgesehen. Nundenn: Fröhlich eingerichtet, ein Template gesucht und installiert. Das erste Template ging nicht, weil es irgendeine %#*(/+ Sublib brauchte. Ich wollte nicht die nächsten 24 Stunden wirklich nicht mit Suchen verbringen und so habe ich wohl oder übel die zweite Wahl eingesetzt. In dieser zweiten Wahl hatte es ein wunderbares Bildchen, das ich natürlich in liebevoller Kleinarbeit angepasst und verschandelt habe. Tja, nach dem ersten mal herumschrauben im Adminpanel ist es dann leider – wohl von sich selbst angewiedert – verschwunden… Nunja, ok. Man kann in ebendiesem Adminpanel RSS-Feed-URLs eintippen: Hab ich gemacht, aber darstellen ist nicht… Nunja. Ich lade dann halt mal ein Modul herunter und installiere es mit dem Installer. Es erscheint, aber nur genügend lange bis ich es konfigurieren konnte. Danach verschwindet es (wohl zum hässlichen Bildchen) und meine Website wird nur noch halb angezeigt, ohne Fehlermeldung, (sogar im Debug-Modus)… Wahrscheinlich die Rache des J’s im Namen des RSS Aggregatormoduls. Das hat mir gereicht: Ich bin zu dumm… Bin ich schon raus oder was?

Auch von PHPWCMS hört man viel Gutes. Dass aber im Titel der Dokumentationsseite eine Art HTML-Tags dargestellt werden, hat mich doch eher abgeschreckt… Nunja, wahrscheinlich ist es ein designerisches Mittel und absichtlich, aber ich hab auch echt keine Nerven dafür das herauszufinden nach dem Joomla!-Debakel… AddOns gibt es leider auch noch nicht viele… PHPWCMS ist wirklich gut und hat sich im Einsatz bewährt, für mich scheints aber nicht zu sein…

Dritter Versuch: e107. Geiler Name, schöne Site, viele Erweiterungen, aber leider ist die Theme-Site nicht erreichbar. Nunja, vielleicht kommt sie ja wieder (nachdem sie sich mit dem hässlichen Bild und dem J-Aggregatormodul genügend unterhalten hat), aber nachdem ich auf der Pluginsite eine Entschuldigung für die lange Downtime gelesen habe, hats mir gereicht. (Ok, ich gebs zu, viel geschlafen habe ich in letzter Zeit nicht, darum bin ich auch nicht so geduldig, aber das ist eine GANZ andere Geschichte 🙂 ).

Naja, dann suche ich halt mal weiter… Die Verlockung, selber was Kleines zu schreiben wird aber immer grösser…. Das wäre dann wohl das gazillionste CMS…