Mittwoch, 14. Oktober 2009

Symfony Class Loader Problem mit dem sfThumbnailPlugin

Wenn man das symfony plugin sfThumbnailPlugin wie folgt installiert:
symfony plugin:install sfThumbnailPlugin

stellt man bei der Benutzung z.B. in einem Modell fest, dass die Klasse sfThumbnail nicht gefunden wird.

Das ist ungewöhnlich, da die Klassen von installierten Plugins in der regel von dem Class Loader gefunden werden.

Die Lösung auf das Problem ist jedoch einfach.

In der Datei
lib\vendor\symfony\lib\config\config\autoload.yml
bringen wir symfony bei, wo nach Klassen gesucht werden sollen.

Es gibt dabei zwei Möglichkeiten:

1. Wir sorgen dafür, dass das /lib -Verzeichnis von allen Plugins durch gesucht werden.

plugins_lib:
  name: plugins lib

  path: %SF_PLUGINS_DIR%/*/lib

  recursive: on



2. Wir fügen nur das /lib -Verzeichnis von dem sfThumbnailPlugin hinzu

sfThumbnailPlugin:
  name: plugins lib

  path: %SF_PLUGINS_DIR%/sfThumbnailPlugin/lib

  recursive: on



Vorsicht!
Die Alternative 1 oben hat (bei mir) dazu geführt, dass embeded Forms nicht mehr funktionieren. In dem Fall kann ich also Alternative 2 empfehlen.

Viel Erfolg!

Dienstag, 6. Oktober 2009

http://www.unternehmermontag.de

Als ich das erste mal einen Webmontag (www.webmontag.de) besuchte, war ich total begeistert. Hier halten Leute interessante, 20-minütige Fachvorträge weil es denen Spaß macht und nicht weil der Chef es befolen hat.

Zwei Monate später (man möge mir verzeihen, dass es so lange gedauert hat ;-) kommt mir der Gedanke:
"Warum nur für Leute aus der Web-Technologie-Branche?"

Kurz entschloßen erstellte ich http://www.unternehmermontag.de
Ein "Webmontag" für jede Branche!

Der Webmontag ist super! Aber da treffen sich die eben nur Web-Technologie-Fachkräfte. Es ist sehr nett unter Spezialisten zu fachsimpeln. Interessante Aufträge springen wohl aber nicht raus. Die anderen Teilnehmern sind ja auch aus der Branche…

Der Unternehmermontag ist breiter gefächert. Mal angenommen einen Versicherungsfachwirt erzählt etwas über Betriebliche Altersvorsorge. Das interessiert sowohl den Bäcker, den Heizungsbauer, den Steuerberater, den Autohändler, den Architekten, der Druckerieunternehmer usw usw.
Das sind also alles potentielle Kunden für den Versicherungsfachwirt.
Der Druckereiunternehmer könnte ein Vergleich zwischen Digital- und Offsetdruck anstellen. Auch er hat potentielle Kunden unter den Zuhörern. Jeder Unternehmer muss mal etwas drucken. Sei es nur die Briefbögen.

Der Unternehmermontag ist aber keine Werbeveranstaltung!
Jeder Referent sollte einen interessanten Fachvortrag halten.
Die Werbung kommt als "spin off"-Produkt.

Also. Viel spaß damit!
Es ist kostenlos!

Dienstag, 15. September 2009

MIME type problem mit Symfony's sfValidatorFile unter PHP 5.3.0

Wenn Sie die Symfony-Klasse sfValidatorFile in der Version 1.2.8 und älter, zusammen mit PHP 5.3.0 nutzen, werden Sie die Fehlermeldung:
"Invalid mime type (image/jpeg; charset=binary)"
erhalten. Hier ein Beispiel mit eine jpg-Datei. Das Problem trift aber auch auf andere mime types zu!

Der Grund für das Problem liegt nicht bei Symfony, sondern in eine Änderung in der PHP-Version 5.3.0 Die PHP-Funktion finfo_file liefert jetzt in der Version 5.3.0 nicht nur den mime type (z.B. "image/jpeg") sondern auch den character set, wie oben bereits in der Fehlermeldung gezeigt:
"image/jpeg; charset=binary"

Das Problem wird hier erläutert:
http://bugs.php.net/bug.php?id=48885
Hier wird deutlich erwähnt, dass es ein Feature und kein Bug ist!

Leider ist diese gravierende Änderung, die die Rückvärtskompatibilität beeinträchtigt, nicht in die Dokumentation eingeflossen:
http://php.net/manual/en/function.finfo-file.php

Entwickler bei ZEND haben den code in ihre lib nachgezogen, sodass es mit beiden Versionen klar kommt.

Bis Symfony nachgezogen hat, können Sie sich mit diesem work around selber helfen. In Ihre Form-Klasse, wo Sie sfValidatorFile nutzen, geben Sie einfach explizit die "neuen" mime types mit:

$this->validatorSchema['bild'] = new sfValidatorFile(array('mime_types' =>
array(
'image/jpeg; charset=binary',
'image/pjpeg; charset=binary',
'image/gif; charset=binary',
'image/png; charset=binary',
'image/x-png; charset=binary',
)));

Und wenn Sie wie ich, auch abwechselnd mit älteren PHP-Versionen arbeiten, geben Sie einfach beide formate mit:

$this->validatorSchema['bild'] = new sfValidatorFile(array('mime_types' =>
array(
'image/jpeg',
'image/pjpeg',
'image/gif',
'image/png',
'image/x-png',
'image/jpeg; charset=binary',
'image/pjpeg; charset=binary',
'image/gif; charset=binary',
'image/png; charset=binary',
'image/x-png; charset=binary',
)));

Viel Erfolg!

Dienstag, 1. September 2009

MySQL Socket-Problem unter Mac OS X

Nach dem wir nun Apache, MySQL und PHP auf dem Mac OS X (Snow Leopard) zum laufen gebracht haben (siehe vorheriger Blogeintrag), wollen wir auch symfony mit dem doctrine OR-Mapper zum fliegen bringen.

Die Installation der 64-bit-Version von MySQL (mysql-5.1.37-osx10.5-x86_64.dmg) unter Snow Leopart ist übrigens problemlos.

Wenn man aber mit doctrine-Mittel gegen die MySQL-Datenbank arbeiten will, bekommt man folgende Meldung:
Warning: PDO::__construct(): [2002] No such file or directory (trying to connect via unix:///var/mysql/mysql.sock) in…

Das hat damit zu tun, dass die php.ini (ursprunglich die php.ini.default vom Snow Leopard bereitgestellt) etwas unglücklich konfiguriert ist.
Das Verzeichnis für MySQL's PDO-Socket ist falsch angegeben. Der Parameter pdo_mysql.default_socket in der php.ini zeigt auf das Verzeichnis
/var/mysql/mysql.sock

Es wäre besser die Zeile mit einem ";" komplett zu deaktivieren, da dann die MySQL defauts verwendet wird.
Ein Blick in die MySQL-Doku verrät jedoch, dass das default-Verzeichns für die MySQL Socket-Datei "/tmp" ist.

Also, das Problem ist entweder so
; pdo_mysql.default_socket=/var/mysql/mysql.sock
oder so
pdo_mysql.default_socket=/tmp/mysql.sock
aus dem Weg geräumt.

Apache und PHP unter Mac OS X einrichten

Hier ein kleines Kochrezept für das Einrichten eines virtual Hosts unter Apache wo auch PHP benötigt wird.

Schritt 1:
Der vorinstallierte Apache Webserver starten:
- In den Systemeinstellungen auf "Freigaben" klicken.
- "Webfreigabe" anwählen.

Jetzt erscheint in dem Dialog rechts die Adresse zu der persönlichen Webseite:
http://[ihre IP-Adresse]/[ihr USER]/
Und die Webseite ihres Computers:
http://[ihre IP-Adresse]

Die Webseite Ihres Computers erreichen sie auch mit dem vordefinierten Hostnamen "localhost":
http://localhost/

localhost hat, neben bei erwähnt, die IP-Adresse 127.0.0.1

Schritt 2:
Tragen Sie in /etc/hosts einen neuen Hostnamen ein, mit dem wir später eine Webseite unter einem eigenem (virtuellem) Host erreichen.
Beispiel:
127.0.0.1 meintestdomain.de

Nach ein neustart des Rechners erreichen wir mit "meintestdomain.de" die selbe Webseite wie mit "localhost", da wir für meintestdomain.de die selbe IP-Adresse wie für localhost vergeben haben.

Schritt 3:
Jetzt konfigurieren wir den Apache Webserver für den Betrieb mit unserem neuen (virtuellen) Host meintestdomain.de

In der Konfigurationsdatei /private/etc/apache2/httpd.conf
aktivieren wir die Zeile
#Include /private/etc/apache2/extra/httpd-vhosts.conf
indem wir das "#" entfernen.
Das ist die Konfigurationsdatei für virtuelle Hosts.

Damit wir eine Testwebseite zum anzeigen haben, legen wir erst das Verzeichnis "meintestdomain" z.B. in unserem "home-Ordner" an.
Neues Verzeichnis: /Users/[ihr User]/meintestdomain
In diesem Verzeichnis legen Sie dann irgend eine HTML Datei ab, mit dem Namen index.html
Kopieren Sie z.B. die Datei, die vom System angelegt worden ist:
http://[ihre IP-Adresse]/[ihr USER]/
Die befindet sich hier: /Users/[ihr USER]/Sites/index.html

In der Konfigurationsdatei
/private/etc/apache2/extra/httpd-vhosts.conf
konfigurieren wir nun unser virtueller Host:

<virtualhost>
ServerName meintestdomain.de
DocumentRoot "/Users/[ihr User]/meintestdomain"
DirectoryIndex index.html
<directory>
AllowOverride All
Allow from All
</directory>
</virtualhost>

Starten Sie jetzt Apache neu, in dem Sie in dem Einstellungen unter "Schritt 1" oben "Webfreigabe" ab- und wieder anwählen.

Jetzt erreichen Sie die Webseite unter:
http://meintestdomain.de/

Schritt 4:
PHP konfigurieren.

Zunächst müssen wir das PHP Modul in Apache aktivieren.
In der uns jetz bekannten Konfigurationsdatei
/private/etc/apache2/httpd.conf
aktivieren wir die Zeile
#LoadModule php5_module libexec/apache2/libphp5.so
in dem wir das "#" entfernen.

Starten Sie jetzt Apache neu, in dem Sie in dem Einstellungen unter "Schritt 1" oben "Webfreigabe" ab- und wieder anwählen.

Machen Sie jetzt ein erster Test. Erstellen Sie in dem Ordner, der in der virtual Host- Konfiguration "DocumentRoot" genannt wurde, die Datei test.php mit folgendem Inhalt:
<?php phpinfo(); ?>

Jetzt erreichen Sie diese Seite mit: http://meintestdomain.de/test.php
Sie sehen sämtliche PHP-Einstellungen.

Unter anderem sehen Sie, dass PHP in dem Ordner /etc nach eine Konfigurationsdatei sucht. Siehe "Configuration File (php.ini) Path"
Beachten Sie, dass "/etc" nur ein Verweis auf den physischen Ordner /private/etc ist!

Sie sehen, dass es keine php.ini in dem Ordner /private/etc gibt. PHP kommt auch ohne Konfigurationsdatei aus! Wenn Sie aber eigene Änderungen machen wollen, kopieren Sie die Datei php.ini.default nach php.ini und machen darin Ihre Einstellungen.

Fertig!

Viel Spaß :-)

Montag, 31. August 2009

Wenn man im mac Finder mehr sehen will...

So bekommt man im Finder versteckte Dateien und Ordner zu sehen.
In einem Terminal-Fenster:
defaults write com.apple.finder AppleShowAllFiles 1

Dann den Finder neu starten:
Tasten gleichzeitig drücken: alt + cmd + esc
Oder ein Klick auf dem Apfel und "Sofort beenden..."
Im Dialog den Finder auswählen und "Neu starten" anklicken.

Samstag, 22. August 2009

symfony (1.2) Bug (sfWidgetFormInputCheckbox)

Das symfony-Framework ist phantastisch!
Die version 1.2 enthällt jedoch einen kleinen Bugg, der leicht zu beheben ist.
Und zwar werden Checkboxen initial mit haken (checked) dargestellt. Ein "jungfräulicher" checkbox soll ja normaler weise "nicht gesetzt" erscheinen.

Zu diesem Bug gibt es übrigens schon ein Ticket:
http://trac.symfony-project.org/ticket/3917

Das Problem liegt in der render-Methode der Klasse sfWidgetFormInputCheckbox, die Sie hier finden:
"dein Projekt"\lib\vendor\symfony\lib\widget\sfWidgetFormInputCheckbox.class.php

So sieht die Methode im Original aus:

public function render($name, $value = null, $attributes = array(), $errors = array())
{
if (!is_null($value) && $value !== false) {
$attributes['checked'] = 'checked';
}
if (!isset($attributes['value']) && !is_null($this->getOption('value_attribute_value'))) {
$attributes['value'] = $this->getOption('value_attribute_value');
}
return parent::render($name, null, $attributes, $errors);
}


Der Fehler ist leicht zu beheben in dem man eine zusätzliche Bedingung in der ersten if-abfrage hinzufügt. Um Probleme bei späteren symfony updates aus dem weg zu gehen, leitet man die vorhandene Klasse selbst ab. Wenn man dabei auch noch die Namenskonvention von symfony für Dateien und Klassen einhällt, wir die Klasse auch noch von dem class loader gefunden ;-)

Neue Datei: MyWidgetFormInputCheckbox.class.php
Klasse mit der überschriebene render-Methode:

class MyWidgetFormInputCheckbox extends sfWidgetFormInputCheckbox
{
public function render($name, $value = null, $attributes = array(), $errors = array())
{
if (!is_null($value) && $value !== false && $value != 0) {
$attributes['checked'] = 'checked';
}
if (!isset($attributes['value']) && !is_null($this->getOption('value_attribute_value'))) {
$attributes['value'] = $this->getOption('value_attribute_value');
}
return parent::render($name, null, $attributes, $errors);
}
}


Die zusätzliche Bedingung ist oben in rot gekennzeichnet (es ist eine null nach dem !=).
Der Wert von $value ist im ungesetzten (unchecked) Zustand 0 (null).

Bei der Erstellung des Widgets in der Form-Klasse, macht es Sinn einen Wert für den gesetzen Zustand zu definieren:

class MySampleForm extends BaseSampleForm
{
public function configure()
{
...
$this->widgetSchema['MyCheckbox'] = new MyWidgetFormInputCheckbox(array(), array('value' => 1));
...
}
}

Duplicate content in Google vermeiden.

Ein klassisches Problem.
Die eigene Webseite ist sowohl unter firmendienste24.de und www.firmendienste24.de erreichbar und das führt zu dem "duplicate content"-Problem in Google.
(firmendienste24.de dient hier durchgängig als Beispiel).

Wie leite ich unter Apache ein request an firmendienste24.de an www.firmendienste24.de weiter?

Man könnte eine VirtualHost-Klammer in Apaches httpd.conf erstellen und dort die Weiterleitung einrichten. Wenn man aber PLESK (z.B. unter SuSe-Linux) nutzt, stellt man schnell fest, dass die Lösung nicht so direkt ist... ;-)

Das Problem liegt darin, daß PLESK die Haupt-Konfigdatei
/srv/www/vhosts/firmendienste24.de/conf/httpd.include
jedes mal wenn man Änderungen in der PLESK-Oberfläche speichert, neu schriebt.

Daher steht in den Kommentaren, dass man die eigenen Settings in
/srv/www/vhosts/firmendienste24.de/conf/vhost.conf
platzieren soll.

Klingt ja zunächst nicht schlecht, wäre es nicht für das unglücklich platzierte include statement in der oben genanten Datei
/srv/www/vhosts/firmendienste24.de/conf/httpd.include
Die ist nämlich hier platziert:

<virtualHost>
...
Include /srv/www/vhosts/firmendienste24.de/conf/vhost.conf
</virtualHost>


Wie man hier sieht kann man hier nicht eine neue VirtualHost-Klammer öffnen...

Das Umleitungsproblem kann man unter Apache aber auch elegant mit einer Datei im root-Ordner der Webseite erschlagen. Die datei trägt den Namen ".htaccess". Eine Änderung darin bedarf nicht ein mal ein Apache Neustart.

Diese Lösung verlangt wiederum, daß das Apache rewrite-Modul geladen ist...

Das geht so:
In der Datei
/etc/sysconfig/apache2
die Variable APACHE_MODULES
um "rewrite" erwietern.

Nach dem Restart von Apache in der Datei
/etc/apache2/sysconfig.d/loadmodule.conf
prüfen ob das Modul rewirite geladen ist.
(Diese Datei wird nach jedem Neustart von Apache geschrieben, und kann daher nicht editiert werden!)
Wir suchen dabei diese zeile:
LoadModule rewrite_module /usr/lib/apache2-prefork/mod_rewrite.so

In der Datei
/srv/www/vhosts/firmendienste24.de/web/.htaccess
folgender Eintrag machen um die Weiterleitung zu vollziehen:

Rewritecond %{HTTP_HOST} !^www\.firmendienste24\.de
RewriteRule (.*) http://www.firmendienste24.de/$1 [R=301,L]

301 ist ein return code für den Browser, der besagt, dass es eine permanente Weiterleitung ist.

Benutzer von dem Framework symfony, stellen schnell fest, dass das Framework eine .htaccess Datei generiert. Der Innhalt kommt aber nicht zum tragen, da in der Datei geprüft wird, ob das rewrite-Modul geladen ist...:
<IfModule mod_rewrite.c>

Freitag, 21. August 2009

Schritt eins :-) Ein AMP-System aufsetzen. Hier unter Windows:

=================
Installation
=================

Software Versions:
Apache - 2.2.11
Mysql - 5.1.34-community
Php - PHP Version 5.2.9-2 (Win32)

Step 1: Default Apache Installation with these settings:
Network domain: localhost
Server Name: localhost
Admin Email: [your Email]
- Install for All Users
- Typical

Step 2: Default installation of mysql
Port: 3306 (default!)
Standard Character Set (Latin1)
Include Bin Directory in Windows Path

Step 3: Download php zip file (php-5.2.9-2-Win32.zip), extract it to your C: drive under c:\php

Step 4: Add these paths to your Windows PATH environment variable, "C:\php", "C:\php\ext",
incase your installation directory is php. Ifn not, replace it with your directory.
Use the System Path variable, as you installer Apache for all users!
Be shure not to use empty spaces in your directory names as some Webservers don't like it.

Step 5: Open httpd.conf, that is located in Apache web server installation folder,
under conf directory i.e., Apache Installation folder > conf > httpd.conf
Add these line at the en of the LoadModule section...
>LoadModule php5_module "c:/php/php5apache2_2.dll"
(Hint!: This module is for Apache Version 2.2)

You can ignore the Hint (alt least unter Windows ;-):
# Add to the end of the AddModule section (in httpd.conf)
AddModule mod_php5.c

Add these lines in the structure...
>AddType application/x-httpd-php .php .php3 .php4 .phtml
>AddType application/x-httpd-php-source .phps

And these line...
Be shure not to place them in some sub structure!
Be shure to use forward shlashes ("/"). Apache want it that way!
A trailing slash may also be necessary for directories.
PHPIniDir "C:/PHP/"

Another way to tell Apache where to find your PHP install directory is to set the
windows environment variable PHPRC (i user both ;-):
PHPRC C:\PHP

Step 6: Goto php installation directory, there u'll find a file named php-ini-recommended.
Rename it to, php.ini
Create an subdirectory C:\PHP\includes for your php include files.

Step 7: Now it's time to modify your php.ini file...
Open the file in notepad.
If you use MySQL, look for "extension=php_mysql.dll" and un comment it,
i.e., delete the ";" at the start of the line.
If you also use PDO (with MySQL), un comment thiese lines to:
extension=php_pdo.dll
extension=php_pdo_mysql.dll
And these line if you use mbstrings and sockest...
extension=php_mbstring.dll
extension=php_sockets.dll
...and so on...
Also look for "extension_dir=", where you place your extension directory ("C:\php\ext" ).
That's the directory where the extensions are, that you just enadled above (php_pdo.dll e.g.)
Also look for "include_path =", where you place your include directory (".;C:\PHP\includes")
(Don't forget to un comment the line! i.e. remove the ";")

Step 8: Reboot the computer - logoff isn't enough!

Step 9: Create a file test.php containing this line and place it in the
Apache document root directory (that's where apache default is looking files to show.
(When using the default installation: C:\Programme\Apache Software Foundation\Apache2.2\htdocs)
Test ist by calling: http://localhost//test.php
Important is the hint at "Loaded Configuration File".
There You shold find the path (with file) to yout php.ini (e.g. "C:\PHP\php.ini ")

Step10: Some PHP based Software need PEAR. You install it with the Bath C:\PHP\go-pear.bat


done :-)