{the magic lies between the brackets}

Autor: Janes Abou Chleih (Seite 3 von 6)

Bachelor of Engineering (B.Eng.) im Bereich Wirtschaftsinformatik an der Hochschule Esslingen
Aktuell als Student: Master of Science (M.Sc.) im Bereicht IT-Management an der FOM Stuttgart

Mehr auf XING: https://www.xing.com/profile/Janes_AbouChleih/cv

Internet Explorer 8 und 11 Group Policies (GPOs, Gruppenrichtlinien) definieren

Um Benutzern in einem Unternehmen vordefinierte Regeln und Rechte einzuräumen gibt es im Active Directory die sog. Group Policy Objects (GPOs) oder zu deutsch Gruppenrichtlinien.
In diesen kann man Usereinstellungen, wie Redirects von lokalen Dateien auf ein Fileshare und Ähnliches veranlassen.
Weiterhin kann man Richtlinien für den Internet Explorer definieren. Darüber geht es hier nun heute.

Im weiteren Verlauf werden die englischen Bezeichnungen der Programme verwendet

Grundsätzlich kann man Gruppenrichtlinien über das „Group Policy Management“.
Nach dem Öffnen klickt man auf den Forest und dann auf die entsprechende Domain, für welche die GPO gelten soll.
Im Ordner „Group Policy Objects“ sind alle GPOs gespeichert. Mit einem Rechtsklick auf diesen Ordner, kann man über die Schaltfläche „New…“ eine neue GPO erstellen.
Neue GPO erstellen

Sobald wir eine GPO erstellt haben, wird diese gelistet und kann mit einem Rechtsklick -> „Edit…“ bearbeitet werden.
Nun gibt es grundsätzlich zwei Wege, wie man Berechtigungen und Einstellungen setzen kann. Einmal computerbezogen und einmal userbezogen.
Ich bevorzuge letztere Variante.

Grundsätzliche Einstellungen für den IE8 (teils veraltet):
Für den Internet Explorer 8 kann man die Einstellungen über Policies -> Administrative Templates -> Windows Compontens -> Internet Explorer definieren.
Die wichtigsten Einstellungen im Unternehmensumfeld sind wohl Restriktionen in Sachen Windows Update und Feedback, sowie Einstellungen in Sachen Proxy und Kompatibilität.
Im Punkt „Browser Menus“ kann man die Feedback Option von Microsoft deaktivieren.
Im Punkt „Internet Control Panel“ kann man die verschiedenen Reiter im Punkt „Internet Optionen“ ein- bzw. ausblenden lassen.

  • Im Unterpunkt „Advanced Page“ kann man die Windows Updates unterbinden, dazu den Punkt „Automatically check for Internet Explorer updates“ auf Disabled setzen
  • Im Unterpunkt „Security Page“ kann man nun Einstellungen für die verschiedenen Zonen im IE definieren:
    • Generell kann man aber beim Punkt „Site to Zone Assignment List“ Seite zu den verschiedenen Zonen hinzufügen.
      Es gilt: (1) Intranet , (2) Trust Site, (3) Internet, (4) Restricted Site
      Damit die Option greift, muss man den Punkt auf Enabled setzen
    • Damit die gesetzten Optionen in den entsprechenden Unterpunkten bspw. Internet Zone greifen, muss man die Punkte „XY“ Zone Template auf Enabled setzen

Erweiterte Einstellungen für den IE11 (neuer Weg):
Generell werden bei einem Update alle Einstellungen des Users auf den neuen Internet Explorer migriert.
Sollte jedoch ein Profil neu erstellt werden, so ziehen nicht mehr alle Einstellungen (im o.g. Punkt IE8). Microsoft hat hier einen neuen Punkt erstellt, welche die Einstellungen vereinfachen sollen.
Dazu einfach auf Preferences -> Control Panel Settings -> Internet Settings gehen und per Rechtsklick einen neuen Eintrag für die jeweiligen IE Version erstellen.
Der Rest sollte sich von selbst erklären ;-)

gpo_pref

Windows Phone 8.1 – Project my Screen

Mit Windows Phone 8.1 ist neben den bereits genannten Funktionen eine neue Funktion namens „Project my Screen“ hinzugekommen.
Diese ermöglicht es den Bildschirminhalt des Smartphones per USB Verbindung auf den Desktop zu übertragen.

Voraussetzung dafür ist die Applikation für den Windows-PC, welche über die Microsoft-Download-Seite zu beziehen ist.

Was anfänglich irritiert ist, dass die Dekstopapplikation standardmäßig im Vollbild läuft und keinerlei Schaltflächen oder eine Maus besitzt.
Die Bedienung ist deshalb im Vollbild sehr unhandlich. Ein Druck auf die Escape, die F-Taste oder Alt-Enter lässt uns dann aber das Programm verkleinern/vergrößern.
Hier kann man dann aber auch die Maus zum Navigieren benutzen.
Über den dann sichtbaren Menüpunkt „Help“ lassen sich dann auch die Key-Shortcuts herausfinden:
Shortcuts_Project_my_Screen

Ich kann mich den Meinungen der User und der Presse hier nur anschließen.
Das Programm ist wirklich praktisch und schnell – es tritt kaum eine merkliche Verzögerung bei der Bildschirmübertragung auf (USB 2.0) .

Project_my_screen_menu

Vergasertausch bei der SV 650

Da ich endlich ungedrosselt unterwegs sein darf und ich kostengünstig an einen guten, ungedrosselten Vergaser gekommen bin, habe ich mich entschieden, nicht die Gasschieber im alten Vergaser zu tauschen, sondern den gesamten Vergaser zu wechseln.

Zuerst muss man den Tank hochklappen und die Airbox entfernen, außerdem ist bei der S-Version die Verkleidung zu entfernen. Dies ist soweit – hoffe ich – nicht erklärungsbedürftig und sollte von jedem beherrscht werden.
Anschließend sollte euch der Vergaser gut zugänglich sein:

Vergaser ist nun sichtbar
Bildquelle: http://www.bluepoof.com/motorcycles/howto/svs_carb_sync

Nun sollte man zuerst alle Kabel und Schläuche entfernen:
Da wären in Fahrtrichtung rechts einmal der Benzinschlauch (1), sowie eine elektrische Steckverbindung für den TPS (2).
Diese sind zu trennen. Dabei ist zu beachten, dass der Tank entweder geleert wird oder der dicke Benzinschlauch, welcher zum Verteiler führt, abklemmt wird. Sonst schießt einem das Benzin entgegen.
Benzinschlauch Steckverbinder

WP_20140222_004

Nun geht man auf die rechte Seite (in Fahrtrichtung) und zieht dort die Standgasschraube aus der Halterung, sowie den Unterdruckanschluss vom Benzinverteiler.

Vergaser_hinten_tstueckWP_20140222_008
Anschließend entfernt man den Chokezug vom Lenker (linke Seite). Dazu entfernt man die zwei Schrauben (7 und 8) , welche in die Bedieneinheit für Blinker, Hupe und Choke führen.
Lenker_ChokeWP_20140208_006

Nun entfernt man die Bedienheit vom Lenker und entfernt den Chokezug vom Chokehebel.
Jetzt muss man noch die beiden Schrauben, welche den Vergaser auf den Zylindern halten lösen.
WP_20140222_001

Anschließend kann man den Vergaser vorsichtig hochziehen und die Gaszüge aushängen, indem man diese aus der Halterung nimmt (Muttern lösen und Zug rausziehen) und den Vergaser etwas dreht.

WP_20140217_008

Abschließend den Vergaser abnehmen. Das war’s!
Jetzt kann man den neuen Vergaser einbauen und dann synchronisieren.

Vergasersynchronisation der SV 650 per Schlauchwaage

Wenn Vergaser nicht synchron sind, so hat das negative Auswirkungen auf den Motorlauf, da die Zylinder nicht mehr mit- sondern gegeneinander arbeiten, also aus dem „Takt“ sind.
Die Folgen sind:

  • schlechte Gasannahme
  • ruppige Lastwechsel
  • weniger Leistung

Will man nun die Vergaser bei der SV 650 synchronisieren, kann man sich Synchronuhren kaufen oder sich selbst ein Messgerät bauen – die Schlauchwaage.
Man benötigt:

  • einen ca. 3m langen, ca 9mm (Innendurchmesser) dicken Schlauch (bspw. aus der Aquaristik)
  • einen ca. 2m langen, ca. 6mm (Innendurchmesser) dicken Schlauch
  • 2 Schlauchschellen zum Fixieren der Schläuche (
  • 2 Schlauchverbinder von 9mm auf 6mm
  • T-Stück 6mm/6mm/6mm
  • Kabelbinder
  •  1 ca. 1,50m hohes, 50cm breites Brett

Der Aufbau ist simpel.
Man montiert das ganze dann wie in der folgenden, top gezeichneten Skizze:

Schlauchwaage_Skizze

Bevor man die Schlauchverbinder aufsteckt und das System „abschließt“ muss man die Waage noch mit einer Flüssigkeit füllen. Besonders eignet sich hier Öl, da es nicht zu zäh und nicht zu flüssig ist.
(Ich nahm Motorendöl, welches ich gerade da hatte, man kann aber auch Speiseöl nehmen… hauptsache nicht zu flüssig, da das ganze so sehr instabil wird und die Ganze stark wackelt!)
Dann füllt man das Öl ein, bis man ca. 1/3 – 1/2 der Höhe erreicht hat (siehe Skizze).

Erstmal zum Prinzip des Ganzen:
Die Vergaser erzeugen einen Unterdruck, sollte der Vergaser nun asynchron sein, so ist der Unterdruck am entsprechenden Vergaser höher/niedriger als am anderen.
Wenn ich nun den Druck an beiden mit der Schlauchwaage vergleiche, zieht es das Öl an einer Seite stärker hoch als an der anderen – die Waage ist ungleich.

Und nun zum eigentlichen Synchronisieren der Vergaser.
Zu aller erst entfernt man die Verkleidung bei der SV 650 S, klappen den Tank hoch und entfernen die Airbox.
Wenn man das getan hat, sollte eure SV etwa so aussehen:

Vergaser_offen

Nun schließt man am Benzinanschluss des hinteren Vergasers das T-Stück an, indem ihr den Benzinschlauch abzieht und jenes am linken Ende anbringt.
Anschließend verbindet man das T-Stück mit dem Benzinanschluss.
Zu guter letzt verbindet man die Schlauchwaage mit dem T-Stück.
Es sollte dann ca. so aussehen:
Vergaser_hinten_tstueck

Am vorderen Vergaser wird es nun kniffliger, denn der Unterdruckanschluss befindet sich an einer schlechten Position, man kommt aber mit etwas Fingerspitzengefühl durch den Rahmen an den Anschluss, welcher mit einer Kappe versehen ist. Diese entfernt man.
Achtung: Die Abdeckung kann etwa festgegammelt sein, mir ist diese gerissen. Jetzt kann man entweder eine neue Abdeckung kaufen (ca. 4€) oder den Schlauch, den wir später anschließen abknicken und mit Kabelbindern fixieren (habe ich getan).
Vergaser_anschluss_vorne

Nachdem man die Kappe entfernt hat, steckt man den Schlauch zur Schlauchwaage auf.
Vergaser_anschluss_vorne_schlauch

Nun kann man den Motor starten. Sollte er nicht richtig laufen, überprüft man, ob die Schläuche fest auf den Anschlüssen sitzen und der Vergaser sonst keine Falschluft zieht.
Nun lässt man den Motor etwas warmlaufen, bis er die Leerlaufdrehzahl erreicht hat und stabil hält.
Wenn man nun auf die Schlauchwaage blickt, sieht man, falls die Vergaser asynchron sind, dass die Flüssigkeit in einer Richtung gezogen ist.
Nun stellt man die Vergaser mit einem Schraubenzieherdreher ein, indem man die Synchronisierungsschraube (siehe Bild unten) minimal dreht und abwartet, wie der Vergaser reagiert (Flüssigkeit wandert in eine Richtung).Synchronschraube

Sind die Vergaser richtig eingestellt, so ist das Öl etwa in Waage (richtig perfekt muss es nicht sein!).

Synchrone Vergaser

Nun die SV wieder zusammenbauen, die Schläuche/T-Stücke abnehmen und das Motorrad wieder in seinen ursprünglichen Zustand zurückversetzen.
Die Abdeckung am vorderen Vergaser anstecken (falls nicht defekt), ansonsten, wie bereits gesagt, neu kaufen oder den Schlauch einfach abknicken und per Kabelbinder fixieren.
Fertig!
Jetzt kann man sich über geschmeidigere Lastwechsel, einen ruhigeren Lauf und etwas mehr Leistung freuen.

[C#/.NET] Eigene Erweiterungen für den Windows Explorer mit SharpShell erstellen

In meinem letzten Beitrag habe ich beschrieben, wie man mit Hilfe einer Microsoft Library eigene Dateiattribute hinzufügen kann.
Auf Grund der Tatsache, dass der Windows Explorer nur die Standardattribute anzeigt (siehe Grafik), müssen wir zur Anzeige der eigenen Attribute entweder

  • ein eigenes Programm entwickeln (Handhabe umständlich)
    oder
  • eine Erweiterung für den Windows Explorer erstellen.

Standardattribute:
Standardattribute_Details

Und um letzteren Punkt handelt dieser Beitrag.

Achtung: Die Library verwendet .NET Framework 4, d.h. eine Erstellung ist nur mit dieser .NET Version möglich und einer IDE, welche diese unterstüzt (VS2010 und höher)

Um zu beginnen, benötigen wir die Library, mit welcher eine Extension erstellt werden kann. Diese findet ihr entweder auf unserer Downloadseite (SharpShell Project) oder auf der Projektpage.

Wir erstellen nun ein neues Projekt vom Typ „Windows Forms-Steuerelementenbibliothek“ (man kann auch einfach eine Klassenbibliothek erstellen) und fügen eine Referenz auf die DLL ein.

Rechtsklick auf das Projekt -> Verweis hinzufügen… ->Durchsuchen -> Durchsuchen -> Datei auswählen.

Nun können wir mit dem eigentlichen Coden beginnen.
SharpShell bietet einige Extensions an, unter Anderem sogenannte Shell Property Sheets/Pages (Erweiterung der Eigenschaftsseite einer Datei/eines Ordners), auf die wir hier näher eingehen.

Zuerst beginnen wir mit dem Sheet, welches alle Pages hält.
Wir erstellen also eine Klasse (ich nenne sie hier einfach mal Sheet) und lassen sie von der abstrakten SharpPropertySheet-Klasse erben. Diese Klasse hält alle nötigen Funktion, welche noch ausgecodet werden müssen.
Die Methoden sind die folgenden:

protected abstract bool CanShowSheet();
protected abstract IEnumerable CreatePages();

Erstere Methode gibt an, ob die Seite angezeigt werden soll.
Letztere gibt die Pages zurück, welche angezeigt werden sollen.

protected override bool CanShowSheet()
{
            return SelectedItemPaths.Count() == 1; //Sobald mindestens eine Datei angewählt, soll die Seite angezeigt werden
}

protected override IEnumerable CreatePages()
{
            CustomPage page = new CustomPage(); //Erstelle eine Page oder mehrere
            return new[] { page }; //und schreibe sie in das Array, welches zurückgegeben wird.
} 

Nun existiert die Klasse CustomPage noch nicht, wir müssen sie erst erstellen.
Da wir ein „Windows Forms-Steuerelementenbibliothek“-Projekt erstellt haben, haben wir schon eine von der IDE vordefinierte Klasse.
Diese nutzen wir nun und benennen wir in „CustomPage“.
Anschließend lassen wir sie von der SharpPropertyPage-Klasse im Namespace „SharpShell.SharpPropertySheet erben.
In den Konstruktor der Klasse schreiben wir einfach mal den Page-Titel:

public CustomPage()
{
     InitializeComponent();
     PageTitle = "Custom Properties";      //Definiert den Page-Titel
}

Diese Klasse hat einige virtual Methoden, wovon wir eine zwingend benötigen:

 public virtual void OnPageInitialised(SharpPropertySheet parent);

Diese Funktion wird aufgerufen, sobald die Seite initialisiert wurde, also ähnlich der Funktion

Form.Load();

Hier bauen wir unsere Logik ein, bspw. können wir hier eine MessageBox aufrufen, welche den Pfad der markierten Datei zurückgibt, bzw. den Pfad der ersten markierten Datei.

    MessageBox.Show(parent.SelectedItemPaths.First().ToString()); 

Oder wir können die CustomProperties, welche wir gesetzt haben auslesen.
Dazu einfach die DSO-Library einbinden und die CustomProperties auslesen.
Ich habe dazu eine ListView eingebettet und fülle diese mit dem Key Bezeichner und dem Wert des Properties:

 public override void OnPageInitialised(SharpPropertySheet parent)
        {
            filePath = parent.SelectedItemPaths.First(); //Pfad der Datei speichern
            OleDocumentProperties myFile = new DSOFile.OleDocumentProperties();
            myFile.Open(@filePath, false, DSOFile.dsoFileOpenOptions.dsoOptionDefault);
            int ctr = 1;
            foreach (DSOFile.CustomProperty property in myFile.CustomProperties)
            {
                ListViewItem key = new ListViewItem(property.Name);
                key.SubItems.Add(property.get_Value());
                lstVw_keys.Items.Add(key);
                ctr++;
            }
            myFile.Close(true);
        } 

Voila, schon ist man eigentlich fertig.
Nun müssen wir allerdings noch ein paar Parameter definieren.
Wir gehen zurück in die Sheet-Klasse und definieren einmal, wie die Clients mit dem verwalteten Code umgehen:

     [ComVisible(true)] 

Nun müssen wir noch definieren, welche Dateien überhaupt betroffen sind:

 [COMServerAssociation(AssociationType.ClassOfExtension,".txt",".css",".js")] 

In diesem Fall also Dateien mit den Endungen .txt, .css und .js.

Jetzt können wir die DLL compilen und schließlich per regAsm einbinden (sehr kompliziert und nervenaufreibend).
Alternativ kann man auch den ServerManager, welcher Teil der SharpShell-Tools ist, benutzen.
Ich zitiere hier jetzt einfach mal meinen Stackoverflow-Beitrag:

I had the same problem while using regasm.exe.
Furthermore there are many things to mention when registering an assembly through regasm.
For example you have to use the x64/x86 version of the regasm.exe, depending on your system.

x64: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regAsm.exe
x86: C:\Windows\Microsoft.NET\Framework\v4.0.30319\regAsm.exe
After having so many problems, I switched to the ServerManager.exe, which is part of the SharpShell Tools. It can be downloaded on the project page.
The usage is quite easy:

  • Load the DLL with „Load server…“
  • Click on „Install Server (xYZ)“
  • And after that on „Register Server (xYZ)“

Restart the Windows Explorer and you should be done (not necessarily needed).

Das Ergebnis sieht in etwa so aus:

CustomPropertiesTab_Pic

Nun seid ihr fertig und könnt eure CustomProperties beliebig hinzufügen, löschen und anzeigen lassen.

Ein Beispielprojekt findet ihr hier: CustomPropertyTab

[PHP] Nutzung eines CAPTCHA Bildes

Wir erstellten ein CAPTCHA Bild im vorigen Beitrag. Nun wollen wir dieses natürlich auch nutzen. Zuerst benötigen wir die PHP-Datei (im folgenden Beitrag generatecaptcha.php). Diese binden wir nun ein. Wir erstellen eine simple HTML-Datei (hier jetzt: index.html). Da die php-Datei eine Bilddatei ausgibt, können wir das Bild einfach per HTML einbinden. Dazu benutzen wir den HTML Image-tag:

<img id="captcha" title="Captcha-Code" alt="" src="generatecaptcha.php" /> 

Dem Image weisen wir nun noch eine ID zu. Wieso? Dazu kommen wir noch. Ein Feld, in welches wir das CAPTCHA eintragen können und einen Button, welcher die Daten absendet, benötigen wir nun noch:

 CAPTCHA Abfrage <img id="captcha" title="Captcha-Code" alt="" src="generatecaptcha.php" /> <form action="checkcaptcha.php" method="POST"><input type="text" name="captcha_solve" /> <input type="submit" /></form> 

Nun gehen wir noch einmal in die generatecaptcha.php: Denn wie soll der Server wissen, welches CAPTCHA wir generiert haben bzw. welcher Text der richtige ist? Wir benötigen sogenannten Session-Variablen. Diese sehen wie folgt aus:

 $_SESSION['mySessionVar'] 

Es ist zu beachten, dass diese Session-Variablen immer global zugänglich sind. Sie müssen also nicht per Schlüsselwort global definiert werden.
Bevor man solche Variablen jedoch nutzt, muss man eine Session auf dem Server starten, dazu folgende Funktion aufrufen:

session_start();
unset($_SESSION['captcha_spam']);

Hier resette ich gleich die Session-Variable captcha_spam, um sicher zu gehen, dass diese nicht mehr gefüllt ist (unnötig, aber sicher ist sicher.)

Nun erstelle ich das Bild in der generatecaptcha.php und schreibe den Text in die Sessionvar:

 $_SESSION['captcha_spam'] = $text; 

Die generatecaptcha.php ist nun fertig, zurück zur index.html.
Hier verweisen wir im form-Tag auf die checkcaptcha.php.
Diese erstellen wir nun:
Da wir in der HTML-Datei die Daten per POST übergeben und der Name des Feldes captcha_solve lautet, holen wir die wie folgt aus dem HTTP-Paket:

 $_POST['captcha_solve'] 

Die Sessionvar holen wir, wie oben beschrieben, per

 $_SESSION['captcha_spam'] 

Sollten der Text in der $_POST-Var und der in der $_SESSION-Var identisch sein, so hat der User den richtigen CAPTCHA-Text eingegeben:

session_start();
if($_SESSION['captcha_spam'] == $_POST['captcha_solve']){
	echo 'RIGHT';
        //TODO HERE
}else{
	echo 'WRONG';
       //FALSCHER CAPTCHA EINGEBEN
}

Jetzt nochmal zu der vorhin genannten ID des Image-Tags.
Will man jetzt noch, dass das CAPTCHA erneuerbar ist, falls es nicht lesbar sein sollte, so sollte dieser Code genügen. Er erneuert das Bild und gibt es aus (ein simpler refresh):

 <img style="cursor: pointer;" onclick="document.getElementById(&quot;captcha&quot;).src = &quot;generatecaptcha.php?r=&quot;+Math.random();" alt="" src="refresh.png" />

Das Math.Random() war nötig, da der Internet Explorer nur Links aufruft/aktualisert, welche sich ändern.

[PHP] Erstellen eines CAPTCHA Bildes

Um Spam zu vermeiden, gibt es viele Möglichkeiten.
Eine der bekanntesten ist das Captcha Bild, in welchem ein Text zu finden ist. Diesen muss man dann einfach in ein Textfeld eintragen.
Aber wie erstellt man ein einfaches Captcha Bild? PHP bietet dafür einige Funktionen, die sogenannten Image-Funktionen.

Als erstes braucht man für ein Bild natürlich eine Größe, bestehend aus der vertikalen Höhe und horizontalen Breite des Bilds:

$width = 150;
$height = 60; 

Da ein Captcha eher in die Breite als in die Höhe geht, wird das Bild natürlich breiter als hoch.

Nun müssen wir erstmal ein (leeres) Bild erstellen, bzw. den Speicher dafür bereitstellen.
Dazu bietet PHP die Funktion:

 $image = imagecreatetruecolor ($width, $height);
$colorbg = imagecolorallocate ( $image, 243, 243, 243 );

Diese nimmt die Höhe und Breite des Bildes als Parameter.
Danach setzen wir die Hintergrundfarbe des Bildes (hier ein Grauton).

Nun zeichnen wir einfach mal einen Text in das bestehende Bild:

$color = imagecolorallocate ( $image, 10, 36, 106 );
imagestring ($image, 5,30, 70, 'This is my text', $color);
//$image = Referenz auf das Bild
//5 (zweiter Parameter) = Der Font
//30 (dritter Parameter) = horizontaler Abstand
//70 (vierter Parameter) = vertikaler Abstand 

Das Ergebnis sieht in etwa so aus:
captcha_mytext_easy

Nun müssen wir es den Bots etwas schwerer machen:
Einen einfach String zu zeichnen und diesen auszugeben ist zwar einfach, aber jedes halbwegs gute AntiCaptcha Programm würde das sofort auslesen können, zumal ständig der gleiche dastehen würde.

Deshalb fügen wir dem Bild noch einige Verzerrungen hinzu.
Lasst uns zuerst mit dem Hintergrund anfangen. Diesen zeichne ich jetzt völlig random Pixel für Pixel.
Dazu durchlaufen wir das Bild einfach Pixel für Pixel (ein Bild ist ja nichts weiter als ein zweidimensionales Pixelarray).
Setzen einen Pixel in einer random ausgewählten Farbe und laufen zum nächstenPixel

 for($y = 1; $y <= $height; $y++) {
    for($x= 1; $x <= $width; $x++) {
        $r = mt_rand(0,255);
        $g = mt_rand(0,255);
        $b = mt_rand(0,255);
        $color = imagecolorallocate ($image, $r , $g , $b);
        imagesetpixel($image,$x - 1 , $y - 1, $color);
    }
}

Das Ergebnis könnte dann so aussehen:
captcha_randombg

Nun machen wir es nochmals schwerer:
Wir zeichnen einfach noch ein paar Striche durch’s Bild.

 for($ctr = 1; $ctr <= 4; $ctr++){
	imagesetthickness($Image, rand(0,10));
	imageline($image, rand(0,$width),rand(0,$height),rand(0,$width), rand(0,$height),imagecolorallocate ( $image, rand(0,255), rand(0,255), rand(0,255) ));
}

Hier werden 4 Striche gezeichnet, welche irgendwo durch das Bild verlaufen und eine Dicke von 0 – 10 haben.
Die Farbe ist auch wieder random.
Die Funktion dafür lautet:

imageline($image, $startposx, $startposy, $endposx, $endposy , $farbe);

Ergebnis:
captcha_bgstripes

Nun zum wohl wichtigsten Part des Bildes, dem Text:

 function generateRandomString($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = "";
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

Hier generieren wir einen String mit der Länge x (als Parameter).
Dazu erstellen wir solange einen String aus den oben gelisteten chars, bis wir die Länge erreicht haben.
Auch ist es wichtig zu wissen, dass wir einfach auf den einzelnen char im string zugreifen können, da ein string ein Array von chars ist (char[]).
Nun weisen wir diesen Text einer Variable (für die Übersichtlichkeit) und erstellen die Farbe des Strings auf dem Bild:

$text = generateRandomString(5); //Random String mit der Länge 5 erstellen
$color = ImageColorAllocate($image, rand(64,255),  rand(128,255) , rand(128,255)); //Farbe des Strings 

Nun nutzen wir, anders als vorhin, eine andere Funktion, um den Text auf das Bild zu schreiben:

 imagettftext($im, $ttfsize, $angle, $x, $y, $color, $ttf, $text); 

Diese bietet einige Vorteile gegenüber

imagestring ($image, $font, $x , $y , $color);

Zum einen kann man einen Winkel definieren, den Text als schräg stellen, zum anderen kann man einen eigenen Font einbinden.
Der Text wird also noch etwas verzerrter dargstellt, bspw.:
captcha_imagestringttf

Fügt man nun all die Funktionen zusammen, die wir in diesem Post behandelt haben, bekommt man ca. folgenden Code (+ einige Anpassungen).
Das Ergebnis sieht wie folgt aus:
captcha_fullcaptcha
[spoiler title=“Vollständiger Code“]


function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

$Width = 150;
$Height = 60;

$Image = imagecreatetruecolor ($Width, $Height);
for($Row = 1; $Row <= $Height; $Row++) {
    for($Column = 1; $Column <= $Width; $Column+=rand(0,5)) {
        $Red = mt_rand(0,255);
        $Green = mt_rand(0,255);
        $Blue = mt_rand(0,255);
        $Colour = imagecolorallocate ($Image, $Red , $Green, $Blue);
        imagesetpixel($Image,$Column - 1 , $Row - 1, $Colour);
    }
}
for($ctr = 1; $ctr <= 4; $ctr++){
	imagesetthickness($Image, rand(0,10));
	imageline($Image, rand(0,$Width),rand(0,$Height),rand(0,$Width), rand(0,$Height),imagecolorallocate ( $Image, rand(0,255), rand(0,255), rand(0,255) ));
}
header('Content-type: image/png');
ob_start();
imagepng($Image);
$data = ob_get_clean();
$im = imagecreatefromstring($data); //Erstelltes Bild von oben aus dem Speicher aufrufen
$text = generateRandomString(5);
$color = ImageColorAllocate($im, rand(64,255),  rand(128,255) , rand(128,255)); //Stringfarbe
$ttf = $_SERVER['DOCUMENT_ROOT']."/assets/font/Fluox.TTF"; //Schriftart
$ttfsize = 25; //Schriftgröße
$angle = rand(0,10);
$t_x = rand(5,30);
$t_y = 40;
imagettftext($im, $ttfsize, $angle, $t_x, $t_y, $color, $ttf, $text);
// Ausgabe des Bildes
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);

[/spoiler]

 

Wie man dieses CAPTCHA Bild nun nutzt, steht im nächsten Beitrag.

[WordPress] Integrieren des WordPress-Blog in die eigene Homepage #2 Suchfunktion

Integrierung des eigentlichen Blogs findet hier in Part1.

Nun haben wir den Blog mit all seinen Posts eingefügt. Es fehlen allerdings noch ein paar essentielle Features eines jeden Blogs.
Beispielsweise die Suchfunktion, um welche es in diesem Post gehen wird.

Um eine Suche starten zu können benötigen wir natürlich zuerst einmal ein Suchfeld.
In HTML werden Eingabefelder (Textboxen, …) mit <input …>-Tags erstellt.
In unserem Fall einem Textfeld sieht dies folgendermaßen aus:

 <input name="s" type="text" size="20" maxlength="20"> 

Der Bezeichner des Parameters ist hier „s“ (ist bei WordPress Pflicht!!), der Typ ist „text“ also Textfelder und die maximale Eingabelänge beträgt 20 Zeichen.
Nun benötigen wir noch einen Button, welcher eine Aktion (hier: die Suche) auslösen soll.
Dafür gibt es in HTML den Typ „submit“:

 <input type="submit"> 

Sobald man nun auf den Knopf drückt, passiert … nichts.
Wieso? … Man muss dem Browser noch sagen, was beim Drücken des Knopfes passieren soll, welche Aktion also ausgeführt werden soll.
In meinem Beispiel soll die search.php-Seite aufgerufen werden.

 <form action="search.php"> input tags here </form>

Nun wird beim Drücken des Buttons die search.php aufgerufen und der Parameter (hier: s), als Post-Parameter (also in der Browserleiste) übergeben.
Das Ergebnis sieht so aus:

http://www.meineDomainHier.de/search.php?s=MeinSuchtext

Nun zum eigentlichen Part, der Such-Page search.php.
Der Aufbau ähnelt sehr stark dem eigentlich Blog. Auch hier wird die Loop verwendet.

  <?php if (have_posts()) : ?>
         <p class="info">Deine Suchergebnisse f&uuml;r '<strong><?php echo $s ?></strong>'</p> <-- Deine Suchergebnisse fuer XYZ --!>
		 <br/>
         <?php while (have_posts()) : the_post(); //The Loop ?> 

In dieser Loop kann man dann wieder, wie im Blog, die einzelnen Daten, welche man benötigt abrufen.
Ich beschränke mich jetzt hier mal auf den Titel und den Inhalt bzw. eine Vorschau dessen.
Die Ausgabe erfolgt hier per PHP wie folgt:

 <?php the_title();
<?php the_excerpt(); // Vorschautext oder the_content(); ?>

Nun schließt man die while-Schleife noch:

 <? endwhile; ?> 

Sollte kein Ergebnis gefunden worden sein, so wird der else-Zweig der if-have-post-Abfrage ausgeführt:

  <?php else : ?>
         <p class="info">Leider wurde f&uuml;r den Suchbegriff '<strong><?php echo $s ?></strong>' nichts gefunden</p>
      <?php endif; ?> 

Damit ist die Suchfunktion fertig.

[WordPress] Integrieren des WordPress-Blog in die eigene Homepage #1 Einstieg + Blog-Hauptseite

Eigentlich wollte ich einen eigenen WordPress-Blog aufziehen, ähnlich diesem hier.
Doch hatte ich schon eine Homepage mit komplettem Template fertig.
So stellte sich mir die Frage, ob ich

  • einen eigenen WordPress-Theme bauen
    oder
  • WordPress in die eigene Homepage integrieren soll.

Ich entschied mich für letzteres.
Wie fängt man, aber an ein fertiges Backend in eine eigene Homepage zu integrieren?
Wie frage ich alles ab?
Man benötigt dazu die Datei wp-blog-header.php, welche sich im Stammverzeichnis des WordPress-Ordners befindet.
Die Datei lädt die ganze Umgebung, d.h. alle benötigten Funktionen, also genau das, was wir wollen.

/**
* Loads the WordPress environment and template.
*
* @package WordPress
*/

Nun lädt man die Datei via php in die eigene Seite:

 <!?php include ('meinPfad/wp-blog-header.php'); ?> 

Dies tut man am besten, der Übersichtlichkeit wegen, vor dem HTML-Tag des Dokuments:

<?php include ('wordpress/wp-blog-header.php'); ?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" />
<title>Blog</title>...

Nun zum eigentlichen Thema, dem Anzeigen von Posts.
In WordPress gibt es die sogenannte Loop.
Diese wird genutzt, um alle Posts mit einer Loop (while-Schleife) zu bekommen. Sie ist ganz einfach und sieht wie folgt aus:

 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php //TO DO HERE ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, keine Posts gefunden'); ?></p>
<?php endif; ?> 

In dieser while-Schleife können nun alle Objekte der Funktion the_post(); ausgelesen werden.
Hier sind folgende für meine Belange wichtig gewesen:

  • Die Post-ID:  the_ID();
  • Der Titel des Posts: the_title();
  • Die Kategorien mit Namen und Category-ID (später)
  • Die Tags: the_tags(…);
  • Das Datum: the_date();
  • Der Autor: the_author();
  • Der Inhalt: the_content();

Diese Funktion ruft man einfach innerhalb der Loop auf. So wird automatisch der Autor, das Datum, … des entsprechenden Post ausgelesen:

 <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_ID(); ?>
<?php the_title(); ?>
<?php the_tags(__('Tags: '), ', ', ' — '); //Die Tags werden mit Komma getrennt ?>
<? the_date();?>
<?php the_author(); ?>
<?php the_content(); ?>
<?php endwhile; else: ?>
<?php _e('Sorry, bisher wurden keine Beiträge geschrieben. Nichts gefunden.'); ?>
<?php endif; ?>

Das einzige, kleine Problem, welches ich noch hatte, war das Auslesen der Kategorien mit Name.
Dies war aber im Endeffekt relativ einfach gelöst, indem man die Funktion get_the_category(); in einer foreach-Schleife ausführte und die Rückgaben ausliest und ausgibt.
Es sollte grob so aussehen (Achtung, etwas buggy mit dem Komma):

<?php _e("Kategorien: "); ?> <?php //the_category(',')
foreach((get_the_category()) as $category) {
    echo $category->cat_name . ', ';
}?>

Im Endeffekt sieht der ganze Code in etwa so aus, wenn man ein paar eigene divs mit einfließen lässt, um die Ausgabe etwas zu designen:

 <div  style="width:450px;min-height:749px;">

<?php if (have_posts()) : while (have_posts()) : the_post(); _e("<br>");?>
<div class="post" id="post-<?php the_ID(); ?>">
<h1><?php the_title(); ?></h1>
<div class="meta"><?php _e("Kategorien: "); ?> <?php //the_category(',')
foreach((get_the_category()) as $category) {
    echo $category->cat_name . ', ';
}?> <br/>
<?php the_tags(__('Tags: '), ', ', ' — '); ?>
<?php _e("Geschrieben am: "); ?> <? the_date(); _e("<br>");?>
<?php _e("Geschrieben von: "); ?><?php the_author(); ?>
<?php edit_post_link(__('edit')); ?>
<?php _e("<hr/>"); ?>
</div>
<div class="storycontent">
<?php the_content(__('(weiterlesen...)')); ?>
</div>
</div>

<?php endwhile; else: ?>
<p><?php _e('Sorry, bisher wurden keine Beiträge geschrieben. Nichts gefunden.'); ?></p>
<?php endif; ?>
</div> 

Der Blog ist eingebunden.
Part 2 mit Suche, Part 3 mit Archiv für Kategorien, … folgen.