Rework me on GitHub

PHPStorm

Edward Gerhold

Mit PHPStorm kann man ebenfalls ein Klassendiagramm erzeugen.

phstorm
Das mit PHPStorm 7.1.3 erzeugte Klassendiagramm vom /framework Verzeichnis, ohne /application oder /www
Im anderen Klassendiagramm fiel mir auf, dass Events gar keine Assoziationen zu den anderen Klassen besitzt. Aber mehr davon spaeter. Ich sitze gerade draussen an einem Baum und fuege das in der U-Bahn generierte Diagramm ein, aber das war es auch schon von mir bis heute abend. Wir sind zusammen unterwegs, da kann ich natrlich nicht am Computer rumhngen.

[write comment]

Uml Übung

Edward Gerhold

Mittlerweile habe ich auch mit den Anforderungen an das System begonnen. Neben Lastenheft, Pflichtenheft, und diversen anderen Artefakten gehören natürlich auch UML Diagramme dazu. Heute vormittag konnte ich mit dem Paket- und Klassendiagram für eine 20" Ansicht beginnen. Wie ich die gleichen Klassen nun in anderen Diagrammen wiederverwende, anstatt sie neu zu erzeugen, und den Codegenerator richtig eingestellt kriege, finde ich dabei gleich mit raus. Hier sind zum Beispiel noch die Multiplizitäten von 0..* einzutragen, sowie die Rollen und Stereotypen. Inzwischen versuche ich mal, das Bild manuell einzubinden. Ich kann mir bereits vorstellen, einen WYSIWYG Editor einzuführen, entweder ich übernehme einen, oder ich bastel mir einen, wobei ersteres professionelle Code Editoren bedeutet und letzteres mehr Arbeit als ich gebrauchen kann, wo ich alles übrige und den unnötigen Aufwand, daß Rad wiederholt zu erfinden, mit zur Begründung aufführen kann. Am besten, ich halte mich an meine eigenen Anforderungsdokumente. Mittlerweile fallen mir viele Funktionen und Redundanzen auf, die ein gewisses Maß an Koordination verlangen, um aus dem Code die wiederholten Muster zu abstrahieren. Seien es Template-Schnipsel, die zusammengesetzt eins ergeben, oder Datenbankfunktionen, zum Beispiel wird die Post-Comment-Reply Geschichte schnell zu einer rekursiven Funktion. Wobei ich mir die als rekursive Serie von Queries sehr lahm denken kann und wahrscheinlich recht mit habe und direkt empfehle, direkt alle Daten auf einmal zu querien und dann einfach drauf zu rekurrieren und für die Ausgabe oder zu ordnen, mit einem Query max pro Tabelle. Quasi ein O(n) wobei n die Tabellen sind. Oder konstant, (O(1)) sollte man einfach nur einen Query meinen. Auf der entsprechenden Ebene, mathematisch filigran wird´s dann wieder polynomisch, äh, hier linear, aber jetzt zum Bildchen...

UML Diagramm
Das ist mein erstes, noch unvollständiges Kontextdiagramm, neben den Use Cases für Admin, Redakteur und Benutzer..

[write comment]

Fehlermeldungen

Edward Gerhold

funktionieren nicht mehr. echo SharedMarkup::errors(errors, "key") funktioniert eigentlich konditional und gutS und ist bereits eine verfeinerte Fehlerbehandlung die bereits im Buch entwickelt wurde. Dennoch ist hier der Fehlerteufel noch am Werken und ich habe noch einiges zu entdecken.

[write comment]

Locale, Partial Templates,Social Network

Edward Gerhold

Die Lokalisierungsfunktionen sind noch nicht aktiv. Ich darf in den Template die Strings nochmal mit dem Language Pack austauschen. Es gibt wiederholende Eingaben und Ausgaben wie bei Settings und User Edit, oder bei Posts hier und Posts da, dafür sind partielle Templates (Ausschnitte, die man vor dem Rendern einblendet) gefragt. EcmaScript 6 bietet Template Strings, die werden auf der Clientside Wunder vollbringen. Ich denke, ES6 landet zuerst in Node und dann in den Browsern. Die Komponenten des Sozialen Netzwerk aus dem Buch mit dem Shared Namespace (Friends, Messages) sind als nächstes zu reparieren. Die Benutzer sollten sich befreunden können und dadurch den Stream ihrer Freunde mitlesen und kommentieren können. Einige Controller sind noch zu basteln. Der für die Timeline, für die für Gäste, für Eingeloggte, für Miteingeschloßene und die Administrationsallmacht, die überall edit Anker stehen hat, wo man was zu verwalten hat. Als ich mal ´ne Mailbox hatte, habe ich auch nicht die Mails anderer gelesen, die habe ich immer geskippt. Aber das Programm von früher könnte eine Grundlage für eine gute Homepage werden...Mal sehen. Jetzt kommt erstmal die Anforderungsdefinition. "/LV10/ Mit Edward´s Homepage soll linux-swt.de übersichtlicher und interaktiver werden." L steht für Lastenheft und V für Visionen (1 Visionen und Ziele, Schablone für Lastenhefte und Pflichtenhefte [Balzert09]). Mit einer vernünftigen Anforderungsdefinition kann ich die Übersicht behalten und verschiedene Programmabläufe erstmal als Programmablaufpläne formulieren und mir einprägen und sie ausarbeiten, und als gesunden Nebeneffekt kann ich RE lernen, was ich für syntax.js noch nachholen muss, was eine lange Anforderungsliste wird.

Fehlermeldungen

33

root

Die Fehlermeldungen funktionieren nicht. Und die Styles sind auch noch nicht ordentlich konzipiert. Das Golden Grid System muss ich auch nochmal downloaden und es sind nicht nur Wrapper Klassen. Die margins sind generiert in einem Kommentar angegeben und müssen wohl selbst ergänzt werden, anhand der Tabelle. Damit kann man die Ausrichtungsabstände ablesen.

[reply]

33

root

Gerade habe ich reply gedrückt, gereplied und der Reply ist nicht angekommen. Hier muss ein Bugfix gemacht werden. Nebenbei solltest du neben dem Requirement Controller um Anforderungen für ein Projekt mit einer Projekt "id" in der Datenbank zu managen auch einen Controller haben, der Bugs tracken kann. Anforderungen und Bugtracker sollten zu linux-swt gehören wie die Mischung aus dem Pro PHP MVC Social Network, was ausgearbeitet werden will, und dem Wordpress für Arme Blog. Posts ist übrigens mehr ein Übungscontroller und Article ist bislang nicht in der Anwendung und die Medien (Drag und Drop Playlists für meinen Hiphop und Webaudio API für eine dritte App, einen Sequenzer, damit ich meine Hip-Hop Beats generieren kann (weil mir das Instrument fehlt und das Credibility gibt)) auch noch nicht.

[reply]

33

root

Der Reply funktioniert nicht. Und wenn man keinen Titel beim Kommentar angibt, versagt die Validierung, was heisst ein @validate required (required ist ein handler) zu entfernen. Mein eben gesagter Gedanke ist erloschen und nun vergangen, eine Information die nun im ewigen Strom verschwand. Es ging im Reply um den Requirements und Bugtracker, den linux-swt.de braucht neben Social Network und Blog, wie ein für die Benutzer offeneres Redaktionssystem um linux-swt.de sachlich zu erweitern.

[reply]

Ohne Titel geht doch

33

root

Was, comment ohne Titel funktioniert wohl. Nur ist die Ordnung verkehrt rum und die Zeitangabe fehlt auch. Und da las ich gerade nur den ersten Comment und dachte, ohne Titel geht nicht. Entschuldigung.

[reply]
[write comment]

Alle Benutzer

Edward Gerhold

Sind rüüücksichtlooos gelöscht worden. Das Benutzermodell ist ausführlicher. Und ALTER TABLE xxx ADD colname INT ist seit heute übrigens mit database->query()->alter(array("table"=>"xxx", "alter"=>"add", "column"=>"colname","type"=>"int", "default"=>"null")); vorzunehmen. Ich habe dafür protected _buildAlter und public alter implementiert. Allerdings war der alte Benutzer nur mit email, first und last. Nun kann man sich mit dem Benutzernamen einloggen. Und weitere Veränderungen kann ich dann alterierend per Software einführen. Mit dem MVC sind die Dinge in Minuten programmiert, wie zum Beispiel eine Oberfläche, um die Tabellen aller Modelle zu managen. Was anderes- ich hab dem controller eine setRedirect() Operation und dem router eine _redirect Property hinzugefügt. Wenn der Router den dispatch durchgeführt hat, und _pass() gerufen hat (ruft den controller mit der action an) und _redirect daraufhin gesetzt ist, wird _pass mit den Daten des _redirect (array("url"=>"", "controller"=>"users", "action"=>"logout", "parameters"=>array()) dann gerufen. Damit sollte dann ein neuer Controller einen neuen View rendern, wenn er am Ende der Funktion wieder gelöscht wird und damit die render Funktion im Destruktor gerufen wird.

[write comment]

Ist fast soweit

Edward Gerhold

Posts, Comments, Replies. Allerdings muss ich was JavaScript zum Einklappen und Ausklappen noch schreiben und default auf eingeklappt stellen, denn die Formulare sind zu gross. Das gleiche kann ich dann direkt mit der Timeline und den vielen Messages machen, dort sammeln sich die Formulare zum sharen einer Message zu einer Message von einem selbst oder einem Friend auch. Und dann werde ich genau damit weitermachen, das mit dem Friend und den Messages für die Homepage zum Starten zu bringen. Ich werde das irgendwie so hinkriegen, meine Artikel, Kategorien. Dann das Benutzer-Netzwerk mit eigener Timeline und Messages mit den Freunden und dann die ACL und den Publisher, um den Content der Seiten zu verändern und die Inhalte zu verbessern. Ausser "Kategorie" werde ich wohl erst "topic" nehmen und in Erinnerung an PCBoard denke ich an Conferences mit Messages und Directories. Ich habe das schonmal mit PHP probiert, da gab es nur HTML4 und CSS2 und ich konnte gar kein JavaScript. Und hatte Message Base und File Directories mit Uploads sowie eine Input type="text" Kommandozeile (wäre heute mit Ajax recht schnucklig). Heute oder morgen kann ich erstmal updaten, dass hier mal wieder was neues zu sehen ist.

[write comment]

Nach dem posten

Edward Gerhold

erscheint die meldung "your post has been created", was bei isset(success) ausgelöst wird, ansonsten erscheint das formular. vielleicht sollte es wieder erscheinen, dass man mehr schreiben kann, aber besser noch, der post selbst sollte als ausstellungsstück erscheinen, dass man ihn auf herz und nieren prüfen kann und mit dem "edit" link direkt editieren. Ansonsten sollte genau hier nach diesem [ich erinnere mich gerade an "preview/ok" für artikel, o.k., vorbei] success einen neuen Controller für die Route wo ich herkam, um dorthin fortzufahren, anstatt zu redirecten... Und. Sie ist seit zehn Minuten hier und wir quasseln.

[write comment]

Warten

Edward Gerhold

Auf jemanden, oder eine Sache, zum Beispiel Software, warten. Bis sie wieder zuhause ist, wird wohl nicht mehr lange sein. Sie hat mich vorgeschickt. Nachdem ich den Boden gesaugt hatte, warf ich mich wieder vor den Computer. Ich habe posts/reply/comment hinzugefügt und habe die Idee, den letzten Aufruf zu speichern, um bei bestimmten routes feststellen zu können, wo der Call herkommt, und wo wir hinwollen. Das Buch verwendet header("Location: ...") für direkte redirects. Anders kann man aber, wenn man mit der ersten Aktion fertig ist, einen weiteren Controller instanziieren, der der neuen Route entspricht. Damit kann man verschiedene Seiten und Aktionen leichter verknüpfen. Hinterher gibt´s Ajax oben drauf und kaum noch Seitenreloads...Muss dringend noch das Design überdenken und mir was aufmalen. Der Rest wird mir beim selbst benutzen einfallen. Oder im Lastenheft oder Pflichtenheft. Selbige Dokumente mit den Schablonen aus dem Lehrbuch der SWT habe ich nun auch endgültig begonnen und einen Einstieg in die Anforderungsdefinitionen gefunden. Jetzt muss ich mir das noch vor die Arbeit am Code rücken und es sollte sitzen, mehr Zeit dafür zu verbringen, um später weniger Zeit mit der Entwicklung zu verbringen, weil ich meinen Anforderungen und Ereignisketten folgen kann. Puh, warte ganz schön lange..;)

[write comment]

Die letzten Minuten

Edward Gerhold

habe ich mit der Implementation von Kommentaren genutzt. Erstmal für den Posts Controller, als comment(id) action, um das zu speichern. Und die Kommentare kann ich jetzt wohl nicht so einfach joinen. Aber ich kann erst die Posts laden, dann die iterieren. Dazu jeweils die Kommentare holen und die dann zum Satz hinzufügen. Den gebe ich dann ans Template. Es muss nicht alles mit einer Abfrage gehen. Das ist ja wohl so schon richtig. foreach posts as post. post comments is -> fetch comments. set view posts posts. Und im Template kann man dann post->comments jeweils unter dem Artikel ausgeben. Wird übrigens bald Zeit für JavaScript um das komfortabel zu machen. All Ajax basiert diesmal auf Promise Interaktion, dachte ich mir besser zukunftsorientiert zu programmieren, und habe dabei bemerkt, dass ich das Framework schon einmal fast in JavaScript wiederholt hatte, als ich eine Datei namens framework.js öffnete. Dennoch startete ich nochmal von vorne.

[write comment]

Ich nehme aber

Edward Gerhold

Die spezialisierten Assoziationen, sprich eine Tabelle für jedes 1..* oder *..1 oder *...* Paar. Allerdings lassen sich 1..1 direkt in der gegenüberliegenden Entität halten. Zum Beispiel hat ein Artikel genau eine Kategorie. Und verschiedene Files je genau einen Artikel. Da reicht es, wenn ein Artikel ein INT für die Kategorie hat und die Files je einen INT für den Artikel. Sofern die Zuordnung genau eins ist. Alles andere kann mit einer Extratabelle für die Relation gelöst werden. Das werden dann viele Tabellen, je eine für eine bestimmte Assoziation, das ist aber so richtig. Anderseits werden es erstmal gar nicht so viele. In kompletter Unternehmenssoftware hingegen treten dann 300 bis 1500 Entitäten auf, las ich im Balzert. Da hatte der Scheer für seinen Band Wirtschaftinformatik das komplette Unternehmen auf DIN A1 gebracht. Es soll auch schon als Vorlage gedient haben. Das Thema Unternehmensmodellierung geht jetzt aber über das Thema planlose Homepage vom Obdachlosen hinaus. Ich hab mich noch weiter mit dem "planlos" zu befassen, im Sinne der Spezifizierung der Homepage. Ich muß mich noch dran gewöhnen, daß zu verschriftlichen.

[write comment]

Posten per Curl

Edward Gerhold

Geht auch noch nicht, man kann keine Credentials mitschicken. Fällt mir gerade auf.

[write comment]

Updaten

Edward Gerhold

Heute vormittag habe ich bestimmt eine Stunde lang das neue Usermodel wiederholt und alle Dateien vervollständigt. Es ist noch nicht fehlerfrei, musste ich beim testen bemerken. Darum werde ich noch eine weitere Stunde einlegen dürfen. Inzwischen habe ich auch vier Varianten für Assoziationen programmiert. Die erste ist einfach spezialisiert und verlinkt Artikel und Kategorie indem deren beiden primary keys die Tabelle bilden. Die zweite Variante erweitert dieses um Felder für den Audio Primary Key, Video, Image. Die dritte Variante beinhaltet genau ein Feld für den Kategoriekey (ist halb spezialisiert oder genau identifizierend) und zwei Felder für die andere Seite der Assoziation. Eins für Key und eins Value, um einen Key "article" oder "comment" zu halten und die Id des Primary Keys der angegebenen anderen Entität. Die vierte generalisiert das und verwendet zwei Key-Value Paare in der Tabelle, daß man die Assoziation frei wählen kann. Darum habe ich die letzte auch einfach Assoziation genannt. Mit dem Framework wird das natürlich als Model implementiert, und durch die Kommentarangaben wird das ORM geregelt. Ein einfaches database->sync(model) reicht dann aus, um die Tabelle zu erzeugen.

[write comment]

Entwickeln

Edward Gerhold

Mittlerweile kann Localize nun jede Sprache, die es einlesen kann auch in memory speichern. Der Clou ist, daß ich die ConfigurationDriver Klasse um /*@readwrite*/ protected _assoc erweitert habe, welche bei true sowohl bei der ini parse_ini_string version, als auch beim json_encode (mein configurationdriverjson, den ich da erstmals hinzufügute) um eine erweiterte Zeile, zum einen die Umwandlung des ini arrays ins stdClass verhindert und den assoc als parsed[path] setzt und zurückgibt, und zum anderen den assoc parameter der json Funktion setzt, und den assoziativen Arrays dann als parsed[path] setzt und zurückgibt. Default wäre ein stdClass Objekt mit Pfeilen. Für die Language Files finde ich die Assoziativen Arrays aber schöner, weil man"TRANSLATE_ME" oder "translate this string" als Key und als DefaultValue nehmen kann. Ich habe den Template Händler um "local TANSLATE ME" in spitzen Template Klammern natürlich erweitert, um den Localize::get("TRANSLATE ME") Call in den Templates zu sparen, und verwende die verwendete Syntax weiter.

[write comment]

timeline

Edward Gerhold

funktioniert auf dem webserver hier wirklich nicht. muss ich auch mal dringend beachten. hab den localhost voller messages.

[write comment]

Drive-By, Drive vorbei.

Edward Gerhold

Kurz mal im Internet, gerade im PHPStorm. Heute vormittag habe ich das neue Usermodel auf dem localhost gesyncht. Und in der Bahn noch Treiber für Encryption installiert, um zum Beispiel md5 oder blowfish wählen zu können, ohne das doppelt zu programmieren, so wie den Javascript oder Stylesheet Treiber. Und eine Localize Klasse, deren Design noch nicht perfekt ist, die aber, ich habe erst ini nehmen wollen, dann aber .json, weil ich an den localhost dachte, language files parsen kann. Allerdings ist die Idee, es mit einer statischen Klasse zu machen, vielleicht nicht so gut. Was ist, wenn ich mal zwei Sprachen gleichzeitig brauche? Insofern ist Localize::* noch zu simpel definiert, indem self:: einen $ _text hält. Ich habe einen "date" type zum Model und zum SQL Treiber hinzugefügt. Das Buch beginnt mit DateTime. Mittlerweile habe ich time und jetzt auch date addiert. Irgendwann später, ich glaube ich geh jetzt noch Abendbrot holen, installiere ich dann das neue Benutzermodel. Und die anderen Klassen neu, weil sich was im Model ändern wird, was nicht mehr kompatibel ist. Die _buildAlter() Operation um Alter Table Queries zu generieren habe ich noch nicht hinzugefügt, daß erstmal ein sync hinhält. Allerdings wird das Framework die hinterher brauchen können. Wichtig ist jetzt schnell mit der Localize Funktion zu arbeiten, damit das mehrsprachig funktioniert.

[write comment]

neu gelernt

Edward Gerhold

habe ich übrigen das cite="" Attribut für viele Tags und auch für section. section cite="/posts/all" ist zum Beispiel die section, die von /posts/all zurückgegeben wird. Das ist schon semantischer als vorher. Ein weiterer Gedanke reicht noch an die Microdata ran, die ich gerade noch in alten Files von mir gelesen habe, als ich meine alte Fehlerseite suchte, die sollte in den Templates zu guter letzt auch nicht fehlen. Aber das cite Attribut finde ich so klasse.

[write comment]

Cool

Edward Gerhold

ist auch, wie leicht man "edit" Links mit dem Pro PHP Framework erzeugen kann, so kann ich zum Beispiel direkt auf der Seite editieren. Das finde ich komfortabel und ich werde das in Zukunft ausarbeiten. Im View wird der User für die zusätzliche Ausgabe mit if user->admin || post->user == user->id geprüft, damit man editieren kann. Ich finde das total praktisch, weil ich mich so nicht in ein extra Backend bewegen muss. Fehlt noch der Post per Script und ich kann die Artikel aus vorher editierten Textdateien von der Kommandozeile schicken, ist doch viel praktischer.

[write comment]

Wie ich sehe

Edward Gerhold

...geht das script. C.method() gibt den langen String zurück Wobei mir die Formatierung gefällt. Das ist auch auf das Golden Grid System, was ich seit gestern anwende, zurückzuführen. Ich glaube, man muss bei dem Golden Grid alles wichtige nur in die wrapper Klasse hüllen. Gerade habe ich files/view für die Thumbnails zum Laufen gebracht, da war noch ein Tippfehler drin. Ähm, was wollte ich nochmal. Achso. Ich habe nun Ideen für viele Controller, Models und assoziative Klassen, das sind die, die nur die Tabellenschlüssel verknüpfen. Letzteres ist mir dann schnell bewusst geworden. Die Artikel haben einen Schlüssel. Die Kategorien haben einen Schlüssel. Und eine dritte Tabelle (die assoziative Klasse) assoziiert einen Artikelschlüssel mit beliebig vielen Kategorieschlüsseln. Bei der ER-Modellierung beim Balzert im Lehrbuch wird das auch behandelt. Unter anderem mit der Tabelle bucht (Kunde bucht Seminar). Im MVC sind Logiken für´s Datenmodell, die Ausgabe und die Geschäftslogik getrennt, aber man kann beliebig viele Modelle in einer Controllerfunktion rufen, um ihre Daten in einem View auszugeben, das sollte man nie zu steif sehen.

[write comment]

Einen Beweis

Edward Gerhold

// Erst lese ich den Code
class C {
  static method() {
     return "Das ist ein Test, ob ich JavaScript in der Textarea normal editieren kann, und was mir dazu einfällt, den Code komfortabel eingeben zu können, da sich das Muster, wie ich das mache, durchgehend wiederholt!";
  }
}
// Und rufe hier die Funktion
C.method();
// Und dann füge ich den Kommentar mit dem Ergebnis hinzu:

Das habe ich mit dem Code gemacht..

//script
ready(function (e) {
 var element = document.querySelector("#ellemennt");
 var code = element.innerText;
 var result = syntaxjs.eval(code);
 element.innerHTML += "/* Resultat von syntax.js ist: "+result+" */";
});
///script

[write comment]

join

Edward Gerhold

das mit dem join war einfach. ich musste nur noch den tabellennamen voranstellen und schon lief das.

[write comment]

unterwegs

Edward Gerhold

die ganze woche schon

[write comment]

Return of the SWT in me

August steht auch im Zeichen des Lehrbuchs der Softwaretechnik Basiskonzepte und Requirements Engineering. Das lese ich mit Begeisterung.

PHPStorm werde ich nochmal für dreissig Tage probieren.

Pro PHP MVC

Ich spiele mit dem Framework aus dem Buch Pro PHP MVC.

Ich habe es abgetippt. Die alte Seite ist hier und im Footer zu finden.