apple,development,life & more
Thursday, August 2. 2007
Dateien im Filemenager vom FCK Editor löschen
Als ich heute gefragt wurde ob der FCKedit auch das Löschen von Dateien
ermöglicht war ich ganz erstaunt, dass er das nicht kann, und hab ihn dann
gleich in meinen Sourcen anhand der Erläuterungen von Bramus
ergänzt. Da sich allerdings einige Kleinigkeiten verändert haben, wollte ich
die einzelnen Schritte noch einmal auflisten.
Die Erweiterungen basieren fast komplett auf den Erklärungen von Bramus,
der dies in seinem Blog alles erwähnt. Danke hierfür.
1.) Ablegen eines entsprechenden ICONS in
2.) Anpassen der Datei frmresourceslist.html
Suchen der Zeile:
Danach folgende Zeile einfügen.
Dann folgenden Block:
durch diesen ersetzen. Hier wird das Bild dann eingefügt.
Zuletzt in der Datei bevor
folgenden Code Block einfügen
3.) Nun geht es an die PHP Funktionen in der commands.php
In der folgenden Datei
muss nur der folgende Code am ENDE vor den ?> eingefügt werden.
4.) Anpassen des Connectors
Im Connector muss noch das Switch Statement angepasst werden.
Sollte nur um folgendes ergänzt werden:
In der 2.4.3 sieht das ganze dann so aus
Viel Spaß damit!
ermöglicht war ich ganz erstaunt, dass er das nicht kann, und hab ihn dann
gleich in meinen Sourcen anhand der Erläuterungen von Bramus
ergänzt. Da sich allerdings einige Kleinigkeiten verändert haben, wollte ich
die einzelnen Schritte noch einmal auflisten.
Die Erweiterungen basieren fast komplett auf den Erklärungen von Bramus,
der dies in seinem Blog alles erwähnt. Danke hierfür.
1.) Ablegen eines entsprechenden ICONS in
CODE:
editor/filemanager/browser/default/images/delete.gif
2.) Anpassen der Datei frmresourceslist.html
CODE:
editor/filemanager/browser/default/frmresourceslist.html
Suchen der Zeile:
CODE:
var sLink = '<a href="#" onclick="OpenFile('' + fileUrl + '');return false;">' ;
Danach folgende Zeile einfügen.
CODE:
// Added by Bramus!
var dLink = '<a href="#" title="Delete file" onclick="DeleteFile('' + escape(fileName) + '');return false;">' ;
var dLink = '<a href="#" title="Delete file" onclick="DeleteFile('' + escape(fileName) + '');return false;">' ;
Dann folgenden Block:
CODE:
return '<tr>' +
'<td width="16">' +
sLink +
'<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
'</td><td> ' +
sLink +
fileName +
'</a>' +
'</td><td align="right" nowrap> ' +
fileSize +
' KB' +
'</td></tr>' ;
'<td width="16">' +
sLink +
'<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
'</td><td> ' +
sLink +
fileName +
'</a>' +
'</td><td align="right" nowrap> ' +
fileSize +
' KB' +
'</td></tr>' ;
durch diesen ersetzen. Hier wird das Bild dann eingefügt.
CODE:
return '<tr>' +
'<td width="35">' +
sLink +
'<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
dLink + '<img alt="" src="images/delete.gif" width="16" height="16" border="0"></a>' +
'</td><td> ' +
sLink +
fileName +
'</a>' +
'</td><td align="right" nowrap> ' +
fileSize +
' KB' +
'</td></tr>' ;
'<td width="35">' +
sLink +
'<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"></a>' +
dLink + '<img alt="" src="images/delete.gif" width="16" height="16" border="0"></a>' +
'</td><td> ' +
sLink +
fileName +
'</a>' +
'</td><td align="right" nowrap> ' +
fileSize +
' KB' +
'</td></tr>' ;
Zuletzt in der Datei bevor
CODE:
window.onload = function()
{
window.top.IsLoadedResourcesList = true ;
}
{
window.top.IsLoadedResourcesList = true ;
}
folgenden Code Block einfügen
CODE:
// Added by Bramus!
function DeleteFile( fileName, fileUrl ) {
if (confirm('Are you sure you wish to delete ' + unescape(fileName) + '?')) {
oConnector.SendCommand( 'DeleteFile', "FileName=" + fileName, DeleteFileCallBack ) ;
}
}
// Added by Bramus!
function DeleteFileCallBack ( fckXml ) {
var oNodes = fckXml.SelectNodes( 'Connector/Error' );
if (oNodes!=null && oNodes.length>0) {
var errNo = parseInt(oNodes[0].attributes.getNamedItem('number').value) ;
switch (errNo) {
case 0 :
break;
case 102 :
case 103 :
alert(oNodes[0].attributes.getNamedItem('originalDescription').value);
break;
default:
alert('DFi: Invalid XML response from connector..');
}
} else {
alert('DFi: Invalid XML response from connector.');
}
Refresh();
}
function DeleteFile( fileName, fileUrl ) {
if (confirm('Are you sure you wish to delete ' + unescape(fileName) + '?')) {
oConnector.SendCommand( 'DeleteFile', "FileName=" + fileName, DeleteFileCallBack ) ;
}
}
// Added by Bramus!
function DeleteFileCallBack ( fckXml ) {
var oNodes = fckXml.SelectNodes( 'Connector/Error' );
if (oNodes!=null && oNodes.length>0) {
var errNo = parseInt(oNodes[0].attributes.getNamedItem('number').value) ;
switch (errNo) {
case 0 :
break;
case 102 :
case 103 :
alert(oNodes[0].attributes.getNamedItem('originalDescription').value);
break;
default:
alert('DFi: Invalid XML response from connector..');
}
} else {
alert('DFi: Invalid XML response from connector.');
}
Refresh();
}
3.) Nun geht es an die PHP Funktionen in der commands.php
In der folgenden Datei
CODE:
editor/filemanager/browser/default/conmectors/commands.php
muss nur der folgende Code am ENDE vor den ?> eingefügt werden.
CODE:
function DeleteFile($resourceType, $currentFolder) {
$sErrorNumber = '0' ;
$sErrorMsg = '' ;
if ( isset( $_GET['FileName'] ) ) {
// Map the virtual path to the local server path.
$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
$sFileName = $_GET['FileName'] ;
if ( strpos( $sFileName, '..' ) !== FALSE ) {
$sErrorNumber = '102' ; // Invalid file name.
$sErrorMsg = 'Invalid file name';
} else {
if ( @unlink($sServerDir.$sFileName) ) {
$sErrorNumber = '0' ; // deleted
} else {
$sErrorNumber = '103' ; // not deleted
$sErrorMsg = 'Could not delete file '.$sServerDir.$sFileName;
}
}
} else {
$sErrorNumber = '102' ; // no file set
$sErrorMsg = 'No file specified';
}
// Create the "Error" node.
echo '<Error number="' . $sErrorNumber . '" originalDescription="' . ConvertToXmlAttribute( $sErrorMsg ) . '" />' ;
}
$sErrorNumber = '0' ;
$sErrorMsg = '' ;
if ( isset( $_GET['FileName'] ) ) {
// Map the virtual path to the local server path.
$sServerDir = ServerMapFolder( $resourceType, $currentFolder ) ;
$sFileName = $_GET['FileName'] ;
if ( strpos( $sFileName, '..' ) !== FALSE ) {
$sErrorNumber = '102' ; // Invalid file name.
$sErrorMsg = 'Invalid file name';
} else {
if ( @unlink($sServerDir.$sFileName) ) {
$sErrorNumber = '0' ; // deleted
} else {
$sErrorNumber = '103' ; // not deleted
$sErrorMsg = 'Could not delete file '.$sServerDir.$sFileName;
}
}
} else {
$sErrorNumber = '102' ; // no file set
$sErrorMsg = 'No file specified';
}
// Create the "Error" node.
echo '<Error number="' . $sErrorNumber . '" originalDescription="' . ConvertToXmlAttribute( $sErrorMsg ) . '" />' ;
}
4.) Anpassen des Connectors
Im Connector muss noch das Switch Statement angepasst werden.
CODE:
editor/filemanager/browser/default/conmectors/commands.php
Sollte nur um folgendes ergänzt werden:
CODE:
case 'DeleteFile' :
DeleteFile( $sResourceType, $sCurrentFolder ) ;
break ;
DeleteFile( $sResourceType, $sCurrentFolder ) ;
break ;
In der 2.4.3 sieht das ganze dann so aus
CODE:
// Execute the required command.
switch ( $sCommand )
{
case 'GetFolders' :
GetFolders( $sResourceType, $sCurrentFolder ) ;
break ;
case 'GetFoldersAndFiles' :
GetFoldersAndFiles( $sResourceType, $sCurrentFolder ) ;
break ;
case 'CreateFolder' :
CreateFolder( $sResourceType, $sCurrentFolder ) ;
break ;
case 'DeleteFile' :
DeleteFile( $sResourceType, $sCurrentFolder ) ;
break ;
}
switch ( $sCommand )
{
case 'GetFolders' :
GetFolders( $sResourceType, $sCurrentFolder ) ;
break ;
case 'GetFoldersAndFiles' :
GetFoldersAndFiles( $sResourceType, $sCurrentFolder ) ;
break ;
case 'CreateFolder' :
CreateFolder( $sResourceType, $sCurrentFolder ) ;
break ;
case 'DeleteFile' :
DeleteFile( $sResourceType, $sCurrentFolder ) ;
break ;
}
Viel Spaß damit!
Posted by Peter Rehm
in Programmierung
at
22:51
| Comments (4)
| Trackbacks (0)
Defined tags for this entry: fck
Sunday, July 8. 2007
$Id Zeilen mit Subversion
In den meisten Quellcodes die man so liest ist eine Id Zeile am Dateianfang zu finden,
die ungefähr so aussieht:
Dies bedeutet dass man die datei test.cpp sieht, zuletzt geändert in Revision 3 um 12:28 am 08.07.2007 von dem Benutzer peterrehm.
Dies ermöglicht einen schnellen Überblick über die Datei.
Die Information wird von Subversion selbst verwaltet.
Damit Subversion das tut, sind ein paar kleine Einstellungen notwendig.
1. Aktivieren der Keywors für die gewünschten Dateien
2. Definieren eines Platzhalters in der Quelldatei
Dazu einfach einen Code wie folgt in die Datei einfügen, je nach
Programmiersprache eben in entsprechender Kommentierung.
3. Datei committen
Mit dem nächsten Commit wird dann automatisch die eingefügt Zeile ersetzt.
Dies wird auch bei jedem weiteren Commit passieren. Die Id Zeile ist aber nicht
für SVN diffs relevant, auch wenn man selbst versuchen sollte die zu ändern,
also wenn man das Datum ändert, wird das nicht mit übertragen.
Die Dateiinformation bleibt solange bestehen bis man eine neuere Version committet,
oder ein anderer Benutzer des SVN Repositorys das übernimmt. Allerdings wird die
Zeile dann auch erst mit dem nächsten update aktualisiert.
Als letzte Information bleibt vielleicht noch zu nennen, dass ein $Log$ Keyword von
den SVN Entwicklern ausdrücklich nicht implementiert werden. Darauf wird in der
FAQ verwiesen.
Update: Fehler wurde behoben, Danke Sebastian!
die ungefähr so aussieht:
CODE:
/* $Id: test.cpp 3 2007-07-08 12:28:37Z peterrehm $ */
Dies bedeutet dass man die datei test.cpp sieht, zuletzt geändert in Revision 3 um 12:28 am 08.07.2007 von dem Benutzer peterrehm.
Dies ermöglicht einen schnellen Überblick über die Datei.
Die Information wird von Subversion selbst verwaltet.
Damit Subversion das tut, sind ein paar kleine Einstellungen notwendig.
1. Aktivieren der Keywors für die gewünschten Dateien
CODE:
svn propset svn:keywords "Id" test.cpp
2. Definieren eines Platzhalters in der Quelldatei
Dazu einfach einen Code wie folgt in die Datei einfügen, je nach
Programmiersprache eben in entsprechender Kommentierung.
CODE:
/* $Id$ */
3. Datei committen
Mit dem nächsten Commit wird dann automatisch die eingefügt Zeile ersetzt.
Dies wird auch bei jedem weiteren Commit passieren. Die Id Zeile ist aber nicht
für SVN diffs relevant, auch wenn man selbst versuchen sollte die zu ändern,
also wenn man das Datum ändert, wird das nicht mit übertragen.
Die Dateiinformation bleibt solange bestehen bis man eine neuere Version committet,
oder ein anderer Benutzer des SVN Repositorys das übernimmt. Allerdings wird die
Zeile dann auch erst mit dem nächsten update aktualisiert.
Als letzte Information bleibt vielleicht noch zu nennen, dass ein $Log$ Keyword von
den SVN Entwicklern ausdrücklich nicht implementiert werden. Darauf wird in der
FAQ verwiesen.
Update: Fehler wurde behoben, Danke Sebastian!
Posted by Peter Rehm
in Programmierung
at
16:44
| Comment (1)
| Trackbacks (0)
Defined tags for this entry: subversion
Monday, April 30. 2007
Focus von beliebigen HTML Elementen entfernen
Hat man ein Element geklickt, und dadurch z.B. einen AJAX Request ausgelöst,
bleibt meist ein Focus auf dem Element. Dies wäre an sich nicht weiter schlimm.
würde der nicht so übel aussehen!

Diesen Focus kann man einfach mit der JavaScript Methode blur() entfernen.
oder wie in meinem Fall mit Prototype:
bleibt meist ein Focus auf dem Element. Dies wäre an sich nicht weiter schlimm.
würde der nicht so übel aussehen!

Diesen Focus kann man einfach mit der JavaScript Methode blur() entfernen.
CODE:
<a href="#bla" onfocus="this.blur()">bla</a>
oder wie in meinem Fall mit Prototype:
CODE:
$('element').blur();
Sunday, April 29. 2007
Internet Explorer 6 & 7, Focus auf Input Elemente nach AJAX Request
Bei einem aktuellen Projekt trat ein seltsames Problem auf.
In jedem Formular wird auf das erste Feld manuell ein focus() gesetzt,
dass man sehr benutzerfreundlich durch die Felder tabben kann und
sofort loslegen kann.
Nachdem ich wie gewohnt zunächst alles in Safari & Firefox entwickelt habe,
war ich sehr erstaunt, dass das focus() nicht an allen Stellen des Projektes
zu sehen war. Nach kurzer Zeit habe ich entdeckt, dass der Focus nur bei
den Seiten nicht angezeigt wird, wo der Inhalt per AJAX nachgeladen wurde.
Es gibt eine sehr einfache wenn auch sehr unschöne Lösung für das Problem.
Man kann den Focus einfach doppelt aufrufen, das habe ich dann in einer
Funktion implementiert, um es einfach wieder zu entfernen, wenn eine andere
Lösung möglich ist.
In jedem Formular wird auf das erste Feld manuell ein focus() gesetzt,
dass man sehr benutzerfreundlich durch die Felder tabben kann und
sofort loslegen kann.
Nachdem ich wie gewohnt zunächst alles in Safari & Firefox entwickelt habe,
war ich sehr erstaunt, dass das focus() nicht an allen Stellen des Projektes
zu sehen war. Nach kurzer Zeit habe ich entdeckt, dass der Focus nur bei
den Seiten nicht angezeigt wird, wo der Inhalt per AJAX nachgeladen wurde.
Es gibt eine sehr einfache wenn auch sehr unschöne Lösung für das Problem.
Man kann den Focus einfach doppelt aufrufen, das habe ich dann in einer
Funktion implementiert, um es einfach wieder zu entfernen, wenn eine andere
Lösung möglich ist.
CODE:
function focus(name)
{
$(name).focus();
// called focus twice due to a bug with ie!!!
$(name).focus();
}
{
$(name).focus();
// called focus twice due to a bug with ie!!!
$(name).focus();
}
Posted by Peter Rehm
in Programmierung
at
15:34
| Comments (0)
| Trackbacks (0)
Defined tags for this entry: internet explorer, javascript
Monday, April 9. 2007
Komische Zeichen in UTF8 aka BOM (Byte order Mark)
Schon lange hab ich mich über die "komischen" Zeichen geärgert, die der Texteditor meines Vertrauens BBEdit am Anfang jeder UTF-8 Datei eingefügt hat. Ich hab dann sogar andere Texteditoren engesetzt, und irgendwie hatte ich immer das gleiche Problem.
Vor allem war ärgerlich, dass ich damit immer wieder nahezu unbrauchbare Dateien ausgeliefert habe, da der IE z.B. eine CSS Datei mit BOM auch einfach mal so ignorieren kann.
Heute habe ich des Rätsels Lösung gefunden. Eben das besagt BOM. Das Teufelszeug.
BOM = Bytereihenfolge-Markierung und wird dazu verwendet um z.B eine UTF-8 Datei als UTF-8 kodiert zu markieren.
Dies macht beim Datenaustausch sicher sinn, kann aber bei der Web oder C++ Entwicklung sich als sehr hinderlich erweisen. Die UTF-8-Kodierung des BOM besteht aus der Bytesequenz EF BB BF, die in den ISO-8859-1-Zeichen  erscheint.
Ich habe nun in BBEdit UTF-8 ohne BOM eingestellt und werde damit hoffentlich endlich Frieden finden
Vor allem war ärgerlich, dass ich damit immer wieder nahezu unbrauchbare Dateien ausgeliefert habe, da der IE z.B. eine CSS Datei mit BOM auch einfach mal so ignorieren kann.
Heute habe ich des Rätsels Lösung gefunden. Eben das besagt BOM. Das Teufelszeug.
BOM = Bytereihenfolge-Markierung und wird dazu verwendet um z.B eine UTF-8 Datei als UTF-8 kodiert zu markieren.
Dies macht beim Datenaustausch sicher sinn, kann aber bei der Web oder C++ Entwicklung sich als sehr hinderlich erweisen. Die UTF-8-Kodierung des BOM besteht aus der Bytesequenz EF BB BF, die in den ISO-8859-1-Zeichen  erscheint.
Ich habe nun in BBEdit UTF-8 ohne BOM eingestellt und werde damit hoffentlich endlich Frieden finden
Monday, March 19. 2007
MSSQL to MySQL konvertieren
In einem aktuellen Projekt stand ich vor der Herausforderung, dass die bisherige Datenbank
in MSSQL gehalten wurde, und ich die Datenbank nur umständlich über ein Weboberfläche
"verwalten" konnte.
Da ich wenigstens die aktuelle Datenstruktur ansehen wollte, den Code der zu dem Projekt
gehört kann eh nicht weiterverwendet werden, musste ich irgendwie ein SQL Statement
erzeugen, was mit dem Tool aber nicht möglich war.
Dann stieß ich auf das MySQL Migration Toolkit, mit welchem man an sich
komfortabel eine MSSQL Datenbank auslesen könnte, und direkt in eine MySQL Datenbank
schreiben kann. Allerdings war, wie nicht anders zu erwarten, der SQL Server nicht von außen
zugänglich.
Die einzige Lösung die somit noch blieb war über ein PHP/ASP Skript, was direkt auf dem
Server liegen kann und soch somit auch verbinden kann. Nach längerer Suche stieß ich auf
das Greenlight SQL Tool.
Aus dem heruntergeladenen ZIP Archiv muss man nur noch die dumpdb.php hochladen und
anpassen. In meinem Fall wollte ich eine MSSQL DB auslesen und in ein MySQL Format bringen.
Standardmäßig sieht der erste teil der Config so aus
Woher die HTTP_POST_VARS kommen sollen, war mir unklar daher habe ich das wie folgt
angepasst.
Nun kann man das Skript über den Browser aufrufen und erhält die Datei direkt zum
Download. Ist dies nicht der Fall fehlt vermutlich PEAR::DB, welches unbedingt vorhanden
sein muss.
Dies kann man allerdings auch direkt in das Verzeichnis hochladen, wenn PEAR nicht
direkt gegeben ist. Auf dies komme ich in einem der nächsten Blog Einträge zurück.
in MSSQL gehalten wurde, und ich die Datenbank nur umständlich über ein Weboberfläche
"verwalten" konnte.
Da ich wenigstens die aktuelle Datenstruktur ansehen wollte, den Code der zu dem Projekt
gehört kann eh nicht weiterverwendet werden, musste ich irgendwie ein SQL Statement
erzeugen, was mit dem Tool aber nicht möglich war.
Dann stieß ich auf das MySQL Migration Toolkit, mit welchem man an sich
komfortabel eine MSSQL Datenbank auslesen könnte, und direkt in eine MySQL Datenbank
schreiben kann. Allerdings war, wie nicht anders zu erwarten, der SQL Server nicht von außen
zugänglich.
Die einzige Lösung die somit noch blieb war über ein PHP/ASP Skript, was direkt auf dem
Server liegen kann und soch somit auch verbinden kann. Nach längerer Suche stieß ich auf
das Greenlight SQL Tool.
Aus dem heruntergeladenen ZIP Archiv muss man nur noch die dumpdb.php hochladen und
anpassen. In meinem Fall wollte ich eine MSSQL DB auslesen und in ein MySQL Format bringen.
Standardmäßig sieht der erste teil der Config so aus
CODE:
$dbpasswd = @$HTTP_POST_VARS["dbpasswd"];
$dbhost = (! empty($HTTP_POST_VARS["dbhost"])) ? $HTTP_POST_VARS["dbhost"]
: "localhost";
$dbname = @$HTTP_POST_VARS["dbname"];
$dbuser = @$HTTP_POST_VARS["dbuser"];
$dbtype = (! empty($HTTP_POST_VARS["dbtype"])) ? $HTTP_POST_VARS["dbtype"]
: (function_exists("mssql_connect") ? "mssql" : "mysql");
$targetType = (! empty($HTTP_POST_VARS["targetType"]))
? $HTTP_POST_VARS["targetType"] : $dbtype;
$dbhost = (! empty($HTTP_POST_VARS["dbhost"])) ? $HTTP_POST_VARS["dbhost"]
: "localhost";
$dbname = @$HTTP_POST_VARS["dbname"];
$dbuser = @$HTTP_POST_VARS["dbuser"];
$dbtype = (! empty($HTTP_POST_VARS["dbtype"])) ? $HTTP_POST_VARS["dbtype"]
: (function_exists("mssql_connect") ? "mssql" : "mysql");
$targetType = (! empty($HTTP_POST_VARS["targetType"]))
? $HTTP_POST_VARS["targetType"] : $dbtype;
Woher die HTTP_POST_VARS kommen sollen, war mir unklar daher habe ich das wie folgt
angepasst.
CODE:
$dbpasswd ='pass';
$dbhost = 'localhost';
$dbname = 'db123';
$dbuser = 'user123';
$dbtype = 'mssql';
$targetType = 'mysql';
$dbhost = 'localhost';
$dbname = 'db123';
$dbuser = 'user123';
$dbtype = 'mssql';
$targetType = 'mysql';
Nun kann man das Skript über den Browser aufrufen und erhält die Datei direkt zum
Download. Ist dies nicht der Fall fehlt vermutlich PEAR::DB, welches unbedingt vorhanden
sein muss.
Dies kann man allerdings auch direkt in das Verzeichnis hochladen, wenn PEAR nicht
direkt gegeben ist. Auf dies komme ich in einem der nächsten Blog Einträge zurück.
Sunday, March 18. 2007
FCK Editor 2.4 und das Phänomen der kleingeschriebenen Pfade
Seit der Einführung von FCK Edit 2.4 wurde ein kleines Detail verändert.
Bisher hat der Editor die Dateien die man hochgeladen hat, immer in
/userfiles/Image/ oder z.b. /userfiles/File/ hochgeladen
Image oder File sind die Ressource Typen.
Seit 2.4 lädt der Editor aber die Dateien immer in /userfiles/image/.
Das ist ziemlich blöd, wenn der Kunde alle seine Bilder in /Image/ liegen hat.
Dazu gibt es 2 Lösungsansätze.
1.) Umbenennen von /Image/ in /image/
Das alte Verzeichnis kann einfach in kleingeschrieben umbenannt werden.
Dies sollte man mit allen Ressource Typen machen, die man verwendet.
Allerdings sollte man beachten, dass man evtl. noch eine Datenbank updaten
muss, wenn sich die Pfade geänder haben.
Dies kann man mit der Anleitung des vorherigen Blog Posts machen.
2.) Man passt die PHP Datein vom FCKEditor an
Seit der neuen Version hat sich hier was verändert
Und zwar ist das strtolower hinzugekommen. Entfernt man dieses verhält sich alles wieder wie gehabt.
Zusammenfassung
Allerdings ist die Methode 1 sicher die zukunftssichere. Da man sonst bei jedem Update wieder an das ändern der
Dateien denken muss.
Bisher hat der Editor die Dateien die man hochgeladen hat, immer in
/userfiles/Image/ oder z.b. /userfiles/File/ hochgeladen
Image oder File sind die Ressource Typen.
Seit 2.4 lädt der Editor aber die Dateien immer in /userfiles/image/.
Das ist ziemlich blöd, wenn der Kunde alle seine Bilder in /Image/ liegen hat.
Dazu gibt es 2 Lösungsansätze.
1.) Umbenennen von /Image/ in /image/
Das alte Verzeichnis kann einfach in kleingeschrieben umbenannt werden.
Dies sollte man mit allen Ressource Typen machen, die man verwendet.
Allerdings sollte man beachten, dass man evtl. noch eine Datenbank updaten
muss, wenn sich die Pfade geänder haben.
Dies kann man mit der Anleitung des vorherigen Blog Posts machen.
2.) Man passt die PHP Datein vom FCKEditor an
Seit der neuen Version hat sich hier was verändert
CODE:
editor/filemanager/browser/default/connectors/php/io.php:34:
return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:
$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;
return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:
$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;
Und zwar ist das strtolower hinzugekommen. Entfernt man dieses verhält sich alles wieder wie gehabt.
CODE:
editor/filemanager/browser/default/connectors/php/io.php:34:
return $GLOBALS["UserFilesPath"] . $resourceType . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:
$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . $resourceType . '/' ;
return $GLOBALS["UserFilesPath"] . $resourceType . $folderPath ;
editor/filemanager/browser/default/connectors/php/io.php:45:
$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . $resourceType . '/' ;
Zusammenfassung
Allerdings ist die Methode 1 sicher die zukunftssichere. Da man sonst bei jedem Update wieder an das ändern der
Dateien denken muss.
Suchen und Ersetzen mit MySQL
Ein Szenario, das sicher einigen bekannt vor kommt. Ein Kunde pflegt seine Daten über
einen längeren Zeitraum. Eines Tages möchte er einen Pfad den er dort immer eingegeben
hat ändern und hat keine Lust dazu alle Artikel nochmals zu bearbeiten.
Er meldet sich und sagt, man solle das doch "kurz" für Ihn erledigen.
Dank der REPLACE Funktion von MySQL auch in der Tat kein Problem.
einen längeren Zeitraum. Eines Tages möchte er einen Pfad den er dort immer eingegeben
hat ändern und hat keine Lust dazu alle Artikel nochmals zu bearbeiten.
Er meldet sich und sagt, man solle das doch "kurz" für Ihn erledigen.
Dank der REPLACE Funktion von MySQL auch in der Tat kein Problem.
CODE:
UPDATE articles
SET content = REPLACE (content,'alt','neu')
SET content = REPLACE (content,'alt','neu')
Posted by Peter Rehm
in Programmierung
at
10:33
| Comments (0)
| Trackbacks (0)
Defined tags for this entry: mysql
Tuesday, December 26. 2006
Erkenntnis des Tages
Mein MacBookPro ist einfach zu schnell um zu messen wie lange eine Zuweisungs oder eine Rechenoperation dauert
Resultat, komplett belegter Ram der mich zu einem Neustart zwang und die Erkenntnis dass 1000000 Zuweisungsoperationen weniger als 0,01 sekunden brauchen.
Juhuu!
Juhuu!
Posted by Peter Rehm
in Programmierung
at
21:07
| Comments (0)
| Trackbacks (0)
Defined tags for this entry: c, programmierung
Friday, December 1. 2006
Performancetests / Profiling in C
Dies musste ich heute einsetzen beim Testen eines Sortieralgorithmus.
Man compiliere sein Programm wie folgt:
Danach muss das Programm einmal ausgeführt werden
Danach kann man sich direkt die Profiling Informationen anzeigen lassen, in meinem Fall:
Man compiliere sein Programm wie folgt:
CODE:
gcc -o ex1b -pg -ansi ex1b.c
Danach muss das Programm einmal ausgeführt werden
CODE:
./ex1b
Danach kann man sich direkt die Profiling Informationen anzeigen lassen, in meinem Fall:
CODE:
gprof ./ex1b
CODE:
granularity: each sample hit covers 4 byte(s) for 0.81% of 1.23 seconds
% cumulative self self total
time seconds seconds calls ms/call ms/call name
91.9 1.13 1.13 1 1130.00 1130.00 _ins_sort [3]
2.4 1.16 0.03 ___sfvwrite [4]
1.6 1.18 0.02 2 10.00 10.00 _print_array [5]
1.6 1.20 0.02 _write [6]
0.8 1.21 0.01 ___vfprintf [7]
0.8 1.22 0.01 _localeconv_l [8]
0.8 1.23 0.01 _printf [9]
0.0 1.23 0.00 1 0.00 0.00 _create_random_array [39]
0.0 1.23 0.00 1 0.00 1150.00 _main [1]
Index by function name
[4] ___sfvwrite [3] _ins_sort [5] _print_array
[7] ___vfprintf [8] _localeconv_l [9] _printf
[39] _create_random_arra [1] _main [6] _write
% cumulative self self total
time seconds seconds calls ms/call ms/call name
91.9 1.13 1.13 1 1130.00 1130.00 _ins_sort [3]
2.4 1.16 0.03 ___sfvwrite [4]
1.6 1.18 0.02 2 10.00 10.00 _print_array [5]
1.6 1.20 0.02 _write [6]
0.8 1.21 0.01 ___vfprintf [7]
0.8 1.22 0.01 _localeconv_l [8]
0.8 1.23 0.01 _printf [9]
0.0 1.23 0.00 1 0.00 0.00 _create_random_array [39]
0.0 1.23 0.00 1 0.00 1150.00 _main [1]
Index by function name
[4] ___sfvwrite [3] _ins_sort [5] _print_array
[7] ___vfprintf [8] _localeconv_l [9] _printf
[39] _create_random_arra [1] _main [6] _write
Monday, November 27. 2006
malloc in C
Die Erkenntnis des Tages: Manche Fehler sind echt dumm!!
Zur Erklärung:
Bei der Fehlermeldung
kommt man schnell zu einem Truschluss. Der Fehler befindet sich nicht in der Zeile 41
sondern liegt einfach an der Header Datei.
Damit sollte das Problem erledigt sein
Zur Erklärung:
Bei der Fehlermeldung
CODE:
structfun.c:41: warning: incompatible implicit declaration of built-in function 'malloc'
kommt man schnell zu einem Truschluss. Der Fehler befindet sich nicht in der Zeile 41
sondern liegt einfach an der Header Datei.
CODE:
#include <stdlib.h>
Damit sollte das Problem erledigt sein
Friday, September 15. 2006
[PHP] String als Zipfile
Wie oft habe ich bereits einen String in ein komprimiertes File schreiben wollen, das vollautomatisiert und zum Download für den User. Allerdings eignet sich dazu das gzip format nicht da die meisten Benutzer mit Windows arbeiten und man ein zusätzliches Tool installieren.
Daher benötigt man das PEAR Module Archive_Zip das hervorragend Zip Dateien erstellen kann. Allerdings benötige ich das Zip File nicht direkt, da ich das File nach dem Download nicht mehr benötige da es veraltet sein könnte. Daher habe ich mir eine Funktion gebaut, die auf Archive_Zip aufbaut, mit der ich das Problem erledigen kann.
Die Funktion stringtozip erstellt temporär das Archiv mit den gewünschten Dateinamen, und löscht danach alles wieder, um nur den String zurückzuliefern.
Aber sehet selbst!
Viel Spaß!
Daher benötigt man das PEAR Module Archive_Zip das hervorragend Zip Dateien erstellen kann. Allerdings benötige ich das Zip File nicht direkt, da ich das File nach dem Download nicht mehr benötige da es veraltet sein könnte. Daher habe ich mir eine Funktion gebaut, die auf Archive_Zip aufbaut, mit der ich das Problem erledigen kann.
Die Funktion stringtozip erstellt temporär das Archiv mit den gewünschten Dateinamen, und löscht danach alles wieder, um nur den String zurückzuliefern.
Aber sehet selbst!
CODE:
/**
* function to create an zip file from an string
* @param string $string content of the file
* @param string $filename name of the file includes the content
* @param string $zipdescription description in the zipfile
* @param string $tmpfolder path for the temporary files with an ending /
*/
function stringToZip($string,$filename,$zipdescription,$tmpfolder)
{
global $cfg;
$rand=rand();
if(!class_exists('Archive_Zip'))
{
// module archive_zip is not existing
return false;
}
if(!is_writable($tmpfolder))
{
// directory is not writeable
return false;
}
if(!file_exists($tmpfolder.$filename))
{
$int_filename=$tmpfolder.$filename;
} else {
$int_filename=$tmpfolder.$filename.'-'.$rand;
}
$fhandler=fopen($int_filename,'a');
fwrite($fhandler,$string);
fclose($fhandler);
$zipHandler=new Archive_Zip($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
$zipHandler->create($int_filename,array('remove_all_path'=>true));
// unlink the file containing the string
unlink($int_filename);
// store the data and delete the temp file
$data=file($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
unlink($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
return join("\n",$data);
}
* function to create an zip file from an string
* @param string $string content of the file
* @param string $filename name of the file includes the content
* @param string $zipdescription description in the zipfile
* @param string $tmpfolder path for the temporary files with an ending /
*/
function stringToZip($string,$filename,$zipdescription,$tmpfolder)
{
global $cfg;
$rand=rand();
if(!class_exists('Archive_Zip'))
{
// module archive_zip is not existing
return false;
}
if(!is_writable($tmpfolder))
{
// directory is not writeable
return false;
}
if(!file_exists($tmpfolder.$filename))
{
$int_filename=$tmpfolder.$filename;
} else {
$int_filename=$tmpfolder.$filename.'-'.$rand;
}
$fhandler=fopen($int_filename,'a');
fwrite($fhandler,$string);
fclose($fhandler);
$zipHandler=new Archive_Zip($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
$zipHandler->create($int_filename,array('remove_all_path'=>true));
// unlink the file containing the string
unlink($int_filename);
// store the data and delete the temp file
$data=file($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
unlink($tmpfolder.date("YmdHis").'-'.$zipdescription.'-'.$rand.'.zip');
return join("\n",$data);
}
Viel Spaß!
Posted by Peter Rehm
in PHP, Programmierung
at
16:17
| Comments (2)
| Trackbacks (0)
Defined tags for this entry: development, php
Wednesday, June 28. 2006
ADODB Table Prefix
Bei fast jedem Projekt arbeitet man mit Tabellen Prefixen, um das Projekt z.b. 2x in der gleichen Datenbank laufen zu lassen. Gestern habe ich angefangen mein Projekt auf ADOBD und dabei festgestellt dass es noch keine eingebaute Funktion für das Verwalten eines Prefixes gibt. Daher hab ich das nun auf meine Anforderungen angepasst.
Mein Prefix liegt in $cfg['tbl_prefix'].
Die Querys werden nun so aufgebaut ("SELECT * FROM ##daten").
Statt Execute nimmt man nun die neue Funktion pExecute.
Diese Funktion muss in die adodb.inc.php implementiert werden, ich hab diese in der aktuellen ADODB Version in Zeile 784 direkt vor Execute plaziert.
Mein Prefix liegt in $cfg['tbl_prefix'].
Die Querys werden nun so aufgebaut ("SELECT * FROM ##daten").
Statt Execute nimmt man nun die neue Funktion pExecute.
Diese Funktion muss in die adodb.inc.php implementiert werden, ich hab diese in der aktuellen ADODB Version in Zeile 784 direkt vor Execute plaziert.
CODE:
/**
* Function to Replace the Prefixes
* After replacing it the SQL Statement will be passed to EXECUTE()
* @param sql SQL statement to execute, ## will be replaced with the Prefix
*/
function &pExecute($sql)
{
global $cfg;
return $this->Execute(str_replace('##',$cfg['tbl_prefix'],$sql));
}
* Function to Replace the Prefixes
* After replacing it the SQL Statement will be passed to EXECUTE()
* @param sql SQL statement to execute, ## will be replaced with the Prefix
*/
function &pExecute($sql)
{
global $cfg;
return $this->Execute(str_replace('##',$cfg['tbl_prefix'],$sql));
}
Tuesday, June 20. 2006
Multi List Drag & Drop - Sajax!
Als ich über die Seite von Tom Westcott gestolpert bin war mir klar, ich muss das in mein neues CMS einbinden. Ich hatte mir damals schon vorgestellt dass das für die Inhaltsstruktur oder für die Sidebar interessant sein könnte, aber ich war damals noch in der Planungsphase.
Als ich dann die Implementation in Serendipity die ich durch Garvin's SuperBlog entdeckt habe getestet habe, war mir klar, genau das will ich auch. Allerdings hat mir nur die AJAX Implementierung zugesagt, da ich ganz genau weiss da manche kunden bei so futuristischen Anwendungen sicher vergessen das abzuschicken. Daher muss das automatisch gemacht werden. Tom hat glücklicherweise auch gleich beide Methoden bereitgestellt.
Allerdings war der Code sehr verworren, und daher habe ich angefangen den Code neu aufzubauen, da ich vor allem im CMS das dann schon sauber einbauen wollte. Anstelle der umfangreicheren Implementation reicht nun folgendes:
Danach muss noch der Pfad in der sajax Datei angepasst werden, dass das einbinden der styles und des JS auch funktioniert.
Die Funktion update_db sollte dann auch an die Gegebenheiten angepasst werden. Die Funktion greift auf die global Datenbankverbindung zu.
Das Auslesen wird dann direkt in dem File gemacht in dem Sie die Liste anzeigen möchten.
Um dies zu vereinfachen habe ich eine Bespiel Datei mitgeliefert, in der Sie das alles sehen können. Dazu auch der passende SQL dump.
Beispielseite - Download
Als ich dann die Implementation in Serendipity die ich durch Garvin's SuperBlog entdeckt habe getestet habe, war mir klar, genau das will ich auch. Allerdings hat mir nur die AJAX Implementierung zugesagt, da ich ganz genau weiss da manche kunden bei so futuristischen Anwendungen sicher vergessen das abzuschicken. Daher muss das automatisch gemacht werden. Tom hat glücklicherweise auch gleich beide Methoden bereitgestellt.
Allerdings war der Code sehr verworren, und daher habe ich angefangen den Code neu aufzubauen, da ich vor allem im CMS das dann schon sauber einbauen wollte. Anstelle der umfangreicheren Implementation reicht nun folgendes:
CODE:
/**
* db settings
*/
$cfg['server']['host'] = "localhost"; // server
$cfg['server']['user'] = "root"; // dbuser
$cfg['server']['pass'] = ""; // password
$cfg['server']['db'] = "sajaxdemo"; // dbname
/**
* start the connection
*/
$conn = mysql_connect ($cfg['server']['host'],
$cfg['server']['user'],
$cfg['server']['pass']);
$result = mysql_select_db ($cfg['server']['db'],$conn);
/**
* include the sajax file
*/
include("sajax.php");
* db settings
*/
$cfg['server']['host'] = "localhost"; // server
$cfg['server']['user'] = "root"; // dbuser
$cfg['server']['pass'] = ""; // password
$cfg['server']['db'] = "sajaxdemo"; // dbname
/**
* start the connection
*/
$conn = mysql_connect ($cfg['server']['host'],
$cfg['server']['user'],
$cfg['server']['pass']);
$result = mysql_select_db ($cfg['server']['db'],$conn);
/**
* include the sajax file
*/
include("sajax.php");
Danach muss noch der Pfad in der sajax Datei angepasst werden, dass das einbinden der styles und des JS auch funktioniert.
CODE:
var $sajax_path='thirdparty/sajax/';
Die Funktion update_db sollte dann auch an die Gegebenheiten angepasst werden. Die Funktion greift auf die global Datenbankverbindung zu.
Das Auslesen wird dann direkt in dem File gemacht in dem Sie die Liste anzeigen möchten.
Um dies zu vereinfachen habe ich eine Bespiel Datei mitgeliefert, in der Sie das alles sehen können. Dazu auch der passende SQL dump.
Beispielseite - Download
Thursday, April 27. 2006
PHPThumb Fehler

Zum Bilder verkleinern und skalieren wird sehr oft phpThumb verwedet was an sich auch toll ist, jedoch hat man oft das Problem, dass man eine Applikation lokal entwickelt und beim Hochladen gibt es dann einen Fehler.
Bei phpThumb kommt es relativ oft zu dem Fehler
Unknown image type identified by ?ph ( 0x3c 0x3f 0x70 0x68 ) in SourceImageToGD
Die ist sehr ärgerlich aber es gibt einen einfach Workaround
Man muss einfach folgende Zeilen in phpThumb/phpThumb.php entfernen:
CODE:
if (@$_SERVER['PATH_INFO']) {
$_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);</em></em>
<em><em>$args = explode(';', substr($_SERVER['PATH_INFO'], 1));
if (!empty($args)) {
$_GET['src'] = @$args[count($args) - 1];</em></em>
<em><em>}
if (eregi('^([0-9]*)x?([0-9]*)$', @$args[count($args) - 2], $matches)) {
$_GET['w'] = $matches[1];
$_GET['h'] = $matches[2];
}
for ($i = 0; $i < count($args) - 2; $i++) {
@list($key, $value) = explode('=', @$args[$i]);
if (substr($key, -2) == '[]') {
$_GET[substr($key, 0, -2)][] = $value;
} else {
$_GET[$key] = $value;
}
}
}
$_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);</em></em>
<em><em>$args = explode(';', substr($_SERVER['PATH_INFO'], 1));
if (!empty($args)) {
$_GET['src'] = @$args[count($args) - 1];</em></em>
<em><em>}
if (eregi('^([0-9]*)x?([0-9]*)$', @$args[count($args) - 2], $matches)) {
$_GET['w'] = $matches[1];
$_GET['h'] = $matches[2];
}
for ($i = 0; $i < count($args) - 2; $i++) {
@list($key, $value) = explode('=', @$args[$i]);
if (substr($key, -2) == '[]') {
$_GET[substr($key, 0, -2)][] = $value;
} else {
$_GET[$key] = $value;
}
}
}
Danach sollte es gehen, mir ist vor allem das Problem bei meinem 1&1 Server aufgefallen, da es lokal meistens funktionierte.
Posted by Peter Rehm
in PHP, Programmierung
at
14:39
| Comment (1)
| Trackbacks (0)
Defined tags for this entry: development, php
(Page 1 of 2, totaling 24 entries)
» next page
Inhalt
Calendar
|
|
March '10 | |||||
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 | ||||
Google Werbung
Archives
Categories
Syndicate This Blog
Getaggte Artikel
Top Referers
pharmacy-generic.co.cc (11)
Statistiken
letzter eintrag: 02.01.2008 11:16
154 geschriebene einträge
103 kommentare wurden erstellt
© Copyright 2006, nerdwg.org design by Luka Cvrk, port for s9y by nerdwg.org

