3rd Party Application Manager

  • Ab sofort steht euch hier im Forum die neue Add-on Verwaltung zur Verfügung – eine zentrale Plattform für alles rund um Erweiterungen und Add-ons für den DSM.

    Damit haben wir einen Ort, an dem Lösungen von Nutzern mit der Community geteilt werden können. Über die Team Funktion können Projekte auch gemeinsam gepflegt werden.

    Was die Add-on Verwaltung kann und wie es funktioniert findet Ihr hier

    Hier geht es zu den Add-ons

Status
Für weitere Antworten geschlossen.
@Selfcontrol,

Kurze Anmerkungen:


Zurückgehen ist was bei dir? Meinst das oben im Browser?

itari

ja , der Zurück im Browser

@itari
du postest ja immer die Diffs von den ARM ipkg paketen
wühlst du dich da händisch durch das angebot oder hast du das automatisiert ?
wäre das auch für die DS508 ipkg angebote realisierbar ?

kannst du mir bitte den unterschied (vor/nachteile) zwischen
mount --bind
und ln (-s)
erläutern ?
zu mount --bind habe ich nichts ausführliches googeln können

die wiederkehrenden mount`s soll man wie hier beschrieben in rc.local eintragen
ist es möglich in der rc.local auf eine andere Datei zu verweisen die dann mit abgearbeitet wird (z.B. /volume1/public/mount.txt)
ich weiss , das ist doppelt gemoppelt , aber da ich vorhabe davon intensiver gebrauch zu machen wäre es für mich übersichtlicher das in einer einzelnen Datei getrennt gelagert zu haben , die auch ein Firmwareupdate überlebt

mfg S
 
Bist du sicher, dass du die letzte Version des Codes verwendet hast (aus meinem letzten Post mit Quellcode hier)? Weil entweder kommt beim Backup eine Vollzugs-oder Fehlermeldung, aber imho kein var_dump().

hatte den Dateianhang von Posting 10 genommen , Fehler wie beschrieben
habe dann mal den Code direkt aus dem Fenster kopiert , damit geht es
scheint wohl nicht identisch zu sein

@Selfcontrol
Den Pfad des Backups werde ich im Formular auch mal noch anzeigen lassen, damit man sehen kann wo die Backups hingehen.

danke


mfg S
 
du postest ja immer die Diffs von den ARM ipkg paketen wühlst du dich da händisch durch das angebot oder hast du das automatisiert ?

Da gibt es Skripte zu - hier

kannst du mir bitte den unterschied (vor/nachteile) zwischen
mount --bind und ln (-s) erläutern ?

ist fast das Gleiche. Leider gab es irgendwann ein paar Knallköpfe bei den Linux-Entwicklern, die meinten ln und ln -s darf man nicht immer und überall machen, weil sich sonst newbies ihr System zerstören. Deswegen muss man nun bei manchen Gelegenheiten auf File-System-Ebene ersatzweise den mount --bind einsetzen. Dieser stammt übrigens aus der NFS-Implemetation, die ja mittlerweile fest im Kernel eingebaut ist.


die wiederkehrenden mount`s soll man wie hier beschrieben in rc.local eintragen. Ist es möglich in der rc.local auf eine andere Datei zu verweisen die dann mit abgearbeitet wird (z.B. /volume1/public/mount.txt)
ich weiss , das ist doppelt gemoppelt , aber da ich vorhabe davon intensiver gebrauch zu machen wäre es für mich übersichtlicher das in einer einzelnen Datei getrennt gelagert zu haben , die auch ein Firmwareupdate überlebt

Die /etc/rc.local überlebt ganz gut :) Aber du kannst natürlich auch einen Aufruf auf eine andere Datei machen. Als Endung würde ich nicht gerade .txt
nehmen, sonder entweder ganz drauf verzichten oder .sh nehmen. In der /etc/rc.local sollte dann der Aufruf wie folgt erfolgen:

Rich (BBCode):
test -x /volume1/public/mount.sh && /volume1/public/mount.sh 2>&1 >/dev/null

Das stellt sicher, dass die /etc/rc.local nicht abstürzt, nur weil vielleicht das Skript nicht verfügbar ist. Außerdem werden eventuelle Fehlermeldungen entsorgt.


mfg S

Grüße
itari
 
Rückmeldung nach Sicherung

Hallo an alle!

Einen ganz herzlichen Dank an alle aktiven Mitglieder ins diesem Forum!!! Ihr habt (und sicher nicht nur) mir sehr geholfen, die DS besser zu verstehen und auszubauen!!

Nun zu meienr Frage: nachdem ich alles sauber installiert habe und auch alles meines Erachtens gut funktioniert, erhalte ich folgende Nachricht auf dem Bildschirm: siehe anhang..... ist das richtig so? oder muss ich noch etwas verändern?

Danke für die Hilfe!!

ulli
 

Anhänge

  • manager.jpg
    manager.jpg
    164,7 KB · Aufrufe: 215
@ulli
Verwende nicht den angehängten Code aus Post #10, sondern den Code der direkt im Post steht. Habe gerade gesehen, dass ich noch einen Debug var_dump() im angehängten Code habe. Diese kommt im Code innerhalb des Posts nicht vor.
Ich werde den angehängten Code heute nach der Arbeit nochmals nachbearbeiten.
Sorry für die Umstände
Gruss

tobi
 
Danke Tobi! werde es heute abend probieren und dann Bescheid geben. Ich lebe in Brasilien und daher 6 Stunden Zeitunterschied.

Liebe Grüße!
 
jo das mit dem var_dump() war bei mir am Anfang auch, hab ihn dann entfernt.
Habe aber einen anderen Fehler festgestellt (oder hab ich nur eine alte Version?). Bei mir wird nach dem 2. Backup im Ordner phpsrc_xxxxxxxxxx ein 2. Ordner phpsrc angelegt. Dieser enthält den kompletten 2.Backupvorgang. Das Hauptverzeichnis (1. phpsrc) enthält das Backup ohne die Original-Verzeichnisse von Synology, also blog, photo, web, etc.
 
Zuletzt bearbeitet:
Bei mir wird nach dem 2. Backup im Ordner phpsrc_xxxxxxxxxx ein 2. Ordner phpsrc angelegt
Das passiert bei mir nicht. Da liegen in /BackupSynology/phpsrcxxx direkt die Verzeichnisse der Anwendungen.
Ich habe z.Z. folgenden Code bei mir laufen und gestern ein Backup gemacht.
PHP:
<?php
ini_set('session.use_cookies','0');
session_start();

$appl_names = array();
//diese beiden Pfad müsst ihr ggf anpassen KEINEN abschliessenden Slash (/)
$path_3rdparty = '/usr/syno/synoman/webman/3rdparty';
$path_phpsrc = '/usr/syno/synoman/phpsrc';
$backup_dir = '/volume1/tmp';
$backup_name = 'backupSynology';
$dh = opendir($path_3rdparty);
while(($res=readdir($dh))!==false){
  if($res != '.' && $res != '..' && is_dir($path_3rdparty.'/'.$res)){
   $appl_names[] = $res; $appl_name=natcasesort($appl_names);
  }
}

if(isset($_POST['delete']) && isset($_POST['del']) && count($_POST['del']) > 0){
 foreach ($_POST['del'] as $wert){
  (file_exists($path_3rdparty.'/'.$wert.'/application.cfg') ? $res=file_get_contents($path_3rdparty.'/'.$wert.'/application.cfg') :$res=0);
 if($res===0){
   continue;
  }
  preg_match('/path.*?=.*?\/phpsrc(\/.*?)\/.*?\.[^\s]*/i',$res,$ret);
  $tt = array();
  exec('rm -r '.$path_3rdparty.'/'.$wert,$tt);
  if(isset($ret[1]) && is_dir($path_phpsrc.$ret[1])){
   exec('rm -r '.$path_phpsrc.$ret[1],$tt);
  }
  if(count($tt) == 0){
   echo 'Erweiterung wurde entfernt';
  }else{
   echo '<pre>'.implode("\r\n",$tt).'</pre>';
  }
  exit;
 }
}elseif(isset($_POST['senden']) && !empty($_POST['Linktext']) && !empty($_POST['Description']) && !empty($_POST['Dir']) && !

empty($_POST['type']) && !empty($_POST['fname'])){
 $att = array();
 $strr = '<strong>Please check the data below carefully as after your confirmation application directories will be created with the parameters given<br />*** No operation will be executed <u>before</u> you confirm by clicking below ***</strong>';
 $strr .= '<br /><br />First the content of <strong>application.cfg</strong> that will be created in <strong>'.$path_3rdparty.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'</strong><br />';
 $str = '';
 $str .= 'text = '.$_POST['Linktext']."\r\n";
 $str .= 'description = '.$_POST['Description']."\r\n";
 $str .= 'type = ';
 ($_POST['type'] == 'embedded') ? $str .= 'embedded' : $str .= 'standalone';
 $str .= "\r\n";
 $str .= 'path = /phpsrc/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname']))."\r\n";
 $_SESSION['appl.cfg'] = $str;
 $_SESSION['appl.dir'] = preg_replace('/\s+|\/+/','',strtolower($_POST['Dir']));

 for($i=0;$i<count($_FILES['file']['name']);$i++){
  if($_FILES['file']['name'][$i] == ''){
   continue;
  }
  $f = file_get_contents($_FILES['file']['tmp_name'][$i]);
  $att[] = array('path'=>$path_phpsrc.'/'.$_SESSION['appl.dir'].'/'.$_FILES['file']['name'][$i],'content'=>$f);
 }
 if(isset($_POST['file_content']) && trim($_POST['file_content']) != ''){
  $att[] = array('path'=>$path_phpsrc.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname'])),'content'=>$_POST['file_content']);
 }
 $_SESSION['appl.att'] = $att;

 echo $strr;
 echo '<pre>'.$str.'</pre>';
 echo '<br />';
 echo 'The following files from your upload will be created:<br /><br />';
 foreach($_SESSION['appl.att'] as $wert){
  echo '<strong>'.$wert['path'].'</strong><br />';
 }
 echo '<br />By clicking <a href="'.$_SERVER['PHP_SELF'].'?'.strip_tags(SID).'">this link</a> all the necessary operation will be written to disk!!!<br />You can abort the operation by <a href="https://'.$_SERVER['SERVER_ADDR'].':5001/webman/index.cgi">clicking this link</a>';
}elseif(isset($_SESSION['appl.cfg']) && isset($_SESSION['appl.dir'])){
 exec('mkdir '.$path_3rdparty.'/'.$_SESSION['appl.dir']);
 exec('mkdir '.$path_phpsrc.'/'.$_SESSION['appl.dir']);
 $fp = fopen($path_3rdparty.'/'.$_SESSION['appl.dir'].'/application.cfg','w');
 fwrite($fp,$_SESSION['appl.cfg']);
 fclose($fp);

 foreach($_SESSION['appl.att'] as $wert){
  $fp = fopen($wert['path'],'w');
  fwrite($fp,$wert['content']);
  fclose($fp);
 }
 unset($_SESSION);
 session_destroy();
 echo '<a href="https://'.$_SERVER['SERVER_ADDR'].':5001/webman/index.cgi">Operations Successfulls done return</a>';
 exit;
}elseif(isset($_POST['backup'])){
 if(!is_dir($backup_dir.'/'.$backup_name)){
  mkdir($backup_dir.'/'.$backup_name);
 }
 $t = time();
 mkdir($backup_dir.'/'.$backup_name.'/3rdparty_'.$t);
 mkdir($backup_dir.'/'.$backup_name.'/phpsrc_'.$t);
 foreach($appl_names as $wert){
  (file_exists($path_3rdparty.'/'.$wert.'/application.cfg') ? $res=file_get_contents($path_3rdparty.'/'.$wert.'/application.cfg') :$res=0);
 if($res===0){
   continue;
  }
  preg_match('/path.*?=.*?\/phpsrc(\/.*?)\/.*?\.[^\s]*/i',$res,$ret);
  exec('cp -R '.$path_3rdparty.'/'.$wert.' '.$backup_dir.'/'.$backup_name.'/3rdparty_'.$t);
  exec('cp -R '.$path_phpsrc.$ret[1].' '.$backup_dir.'/'.$backup_name.'/phpsrc_'.$t);
 }
 die('Data seccesfully wrote to backup directory');
}elseif(isset($_POST['restore']) && isset($_POST['time']) && !empty($_POST['time'])){
 if(!is_dir($backup_dir.'/'.$backup_name.'/3rdparty_'.$_POST['time']) || !is_dir($backup_dir.'/'.$backup_name.'/phpsrc_'.$_POST['time'])){
  die('Data could not be restored because eighter Backup Path was not given OR the subdirectories (3rdparty phpsrc) do not exist in given path');
 }
 exec('cp -Rf '.$backup_dir.'/'.$backup_name.'/phpsrc_'.$_POST['time'].'/* '.$path_phpsrc);
 exec('cp -Rf '.$backup_dir.'/'.$backup_name.'/3rdparty_'.$_POST['time'].'/* '.$path_3rdparty);
 die('Data succesfully restored');
}else{
?>
 <html>
 <head>
 <title>3rd Party Application Remover</title>
 <style>body,input,textarea,td,option,select{font:11px Verdana}fieldset{border:1px solid #bbb}</style>
 </head>
 <body>
 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
 <fieldset><legend>installed 3rd-party-applications / remover</legend><table border="0"><tr>
 <?php
 $ii=0;
 foreach ($appl_names as $wert){
  echo '<td width="120px"><input type="checkbox" name="del[]" value="'.$wert.'" />'.$wert.'</td><td>';
  if (++$ii % 7 == 0) echo '</td></tr><tr>';
 }
 ?>
 </tr></table>
 <input style="margin-left:150px;margin-top:5px;" type="reset" value="reset form" />
 <input style="margin-left:320px" type="submit" name="delete" value="remove 3rd-party-apps" />
 </fieldset></form>
 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data">
 <fieldset><legend>create 3rd-party-application</legend>
 <span style="padding-right:53px">text for the link:</span> <input size="90" type="text" name="Linktext" /><br/>
 <span style="padding-right:20px">description for tooltip:</span> <input size="90" type="text" name="Description" /><br/>
 <span style="padding-right:25px">application directory:</span> <input size="90" type="text" name="Dir" /><br/>
 <span style="padding-right:51px">application type:</span> <select name="type">
 <option value="embedded" selected="selected">embedded</option>
 <option value="popup">popup</option></select><br/>
 <span style="padding-right:96px">filename:</span><input input size="90" type="text" name="fname" /><br/>
 <span style="padding-right:86px">upload file:</span><input size=89 type="file" name="file[]" /><br/>
 <span style="padding-right:86px">upload file:</span><input size=89 type="file" name="file[]" /><br/>
 <span style="padding-right:86px">upload file:</span><input size=89 type="file" name="file[]" /><br/>
 <span style="padding-right:86px">upload file:</span><input size=89 type="file" name="file[]" /><br/>
 <span style="padding-right:86px">upload file:</span><input size=89 type="file" name="file[]" /><br/>
 <span style="padding-right:83px">file content:</span><textarea name="file_content" rows="10" cols="87"></textarea><br/>
 <input style="margin-left:150px" type="reset" value="reset form" /><input style="margin-left:330px" type="submit" name="senden" value="create 3rd-party-apps" />
 </fieldset>
 <fieldset><legend>Backup and Restore 3rd Party Applications</legend>
 <fieldset><legend>Backup 3rd Party Applications</legend>
 <input type="submit" name="backup" value="Create Backup" />
 </fieldset>
 <fieldset><legend>Restore 3rd Party Applications</legend>
 <span style="padding-right:20px">Select Date for restore</span><select name="time">
 <?php
 $path = $backup_dir.'/'.$backup_name;
 $dh = opendir($path);
 $arr = array();
 while(($res=readdir($dh))!==false){
  if($res != '.' && $res != '..' && is_dir($path.'/'.$res)){
   $t = substr($res,strpos($res,'_')+1);
   $arr[] =intval($t);
  }
}
$arr = array_unique($arr);
rsort($arr);
foreach($arr as $wert){
 if(!empty($wert) && $wert != 0){
   echo '<option value="'.$wert.'">'.date('d.m.y H:i:s',$wert).'</option>';
 }
}
?>
</select>
<input type="submit" name="restore" value="Restore" />
</fieldset>
</fieldset>
 </form>
</body>
 </html>
<?php
}
?>
...ohne die Original-Verzeichnisse von Synology, also blog, photo, web, etc.
That's not a bug that's a feature :D
Es wird nur kopiert was auch unter /usr/syno/synoman/webman/3rdparty ein Verzeichnis und eine appliaction.cfg hat. Genaugenommen sind das ja keine 3rdParty-Appls, denn die kommen von Synology selber (via Firmware) ;)

Gruss

tobi
 
Hallo tobi,

habe den code aus #28 benutzt und funktioniert klasse! Danke!!! ....nur ein kleiner Rechtschreibfehler bei der Ausgabe nach dem Backup....tut aber nix zur Sache! (seccesfully --> successfully)

Grüße!

ulli
 
Hallo tobi,

habe den code aus #28 benutzt und funktioniert klasse! Danke!!! ....nur ein kleiner Rechtschreibfehler bei der Ausgabe nach dem Backup....tut aber nix zur Sache! (seccesfully --> successfully)

Grüße!

ulli
Schön, dass dir das Teil gefällt. Und du hast bestimmt nicht den einzigen Rechtschreibefehler gefunden ;)
Habe aber noch gesehen, dass im obigen Code noch etwas subotimal ist
PHP:
 <?php
ini_set('session.use_cookies','0');
session_start();

$appl_names = array();
//diese beiden Pfad müsst ihr ggf anpassen KEINEN abschliessenden Slash (/)
$path_3rdparty = '/usr/syno/synoman/webman/3rdparty';
$path_phpsrc = '/usr/syno/synoman/phpsrc';
$backup_dir = '/volume1/tmp';
$backup_name = 'backupSynology';
$dh = opendir($path_3rdparty);
while(($res=readdir($dh))!==false){
  if($res != '.' && $res != '..' && is_dir($path_3rdparty.'/'.$res)){
   $appl_names[] = $res;   
  }
}
natcasesort($appl_names);
Das Sortieren innerhalb der Schleife macht nicht soviel Sinn :D

Tipp: Wenn du nach einem FW Upgrade das Backup zurückspielen willst, dann geht das am schnellsten manuell über die Konsole, weil die 3rd Party Appl ja erst mal weg sind. Zusätzlich nicht vergessen die php.ini und die httpd.conf-sys wieder anzupassen (könnte ich eigentlich noch einbauen, dass diese beiden Dateien auch gesichert werden)
Dazu bei Zeile 104 die folgenden 2 exec Statements einfügen
PHP:
} //Schliessende Klammer auf Zeile 104 NICHT nochmals einfügen
 exec('cp -f /usr/syno/apache/conf/httpd.conf-sys '.$backup_dir.'/'.$backup_name);
 exec('cp -f /usr/syno/etc/php.ini '.$backup_dir.'/'.$backup_name);
Unbedingt itaris nächsten Post lesen bevor ihr nach einem FW-Upgrade die Conf-Files zurückspielt!
Gruss

tobi
 
Zuletzt bearbeitet:
Zusätzlich nicht vergessen die php.ini und die httpd.conf-sys wieder anzupassen (könnte ich eigentlich noch einbauen, dass diese beiden Dateien auch gesichert werden)

Das ist möglicherweise nicht so sinnvoll, da ich bislang bei jedem Firmware-Update auch Änderungen in diesen Dateien gesehen habe; die wären dann ja weg.

itari
 
stripslashes und ^M zeichen

Hallo leute,

Vielleicht habe ich nicht gut in die verschiedene posts gesucht aber diese habe ich meiner meinung nach noch nicht gesehen...
Als ich php code mit dem Manager eintrage (via 'file content') bekomme ich überall wo ein ' oder ein " steht ein backslash dabei...:o

Deswegen hab ich eine kleine änderung gemacht nämlich:
PHP:
$att[] = array('path'=>$path_phpsrc.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname'])),'content'=>$_POST['file_content']);

wird:
PHP:
$att[] = array('path'=>$path_phpsrc.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname'])),'content'=>str_replace(chr(13),'',stripslashes($_POST['file_content'])));

Und auf einmal sind die ^M's und die backslashes verschwunden...:eek:

Grüße

Wizjos
 
Gut gesehen - gut gelöst.

itari
 
Wo finden wir den letzten Stand als Gesamtwerk?

Hallo zusammen,

ich bin gerade über diesen Thread gestolpert und völlig begeistert von der Idee, die 3rd party apps leichter administrieren zu können. Leider ist mir nicht mehr klar, mit welchem Code ich hier anfangen und welche Zeilen alle noch geändert werden müssen, damit der 3rd party manager mit allen Features funktioniert. Könnt ihr den neuen Besuchern hier etwas unter die Arme greifen und die aktuellste Version nochmal am Stück posten?

Herzlichen Dank und Danke für die tollen Skripte!
Huettenwirt
 
Ja - das wäre ganz praktisch.
 
mir würde auch ein letzter Beitrag hier mit dem aktuellen Code reichen :-)
 
Vielleicht tu ich nun dem einen oder anderen ganz doll Unrecht, aber ihr seid alle faule Säcke. :D

Die 3rd-party-apps - zumindest von mir - sollen nicht einfach blöd installiert werden, sondern Ideen liefern, wie man mit Skripten auf einer DS das ein oder andere schicker machen kann. Vielleicht auch das Verwalten von 3-rd-parties. Aber wenn man sich ein wenig in die Materie einarbeitet (das kann schon ein halben Leben dauern :D), dann kann man sich locker aus den Threads die Dinge zusammenstellen. Schließlich wollen wir doch alle unsere Spaß haben, sonst hätten wir uns doch nicht aus Spaß mit der Computerei und den DSen befasst und zum Spaß gehört auch das angestrengte Basteln.

Wer kommerziell eine 3rd-party-Apps bei mir bestellt, bekommt natürlich auch exklusiv von mir was geliefert und muss sich natürlich nicht mit den Details beschäftigen. ;)

itari
 
Hallo leute,

Vielleicht habe ich nicht gut in die verschiedene posts gesucht aber diese habe ich meiner meinung nach noch nicht gesehen...
Als ich php code mit dem Manager eintrage (via 'file content') bekomme ich überall wo ein ' oder ein " steht ein backslash dabei...:o

Deswegen hab ich eine kleine änderung gemacht nämlich:
PHP:
$att[] = array('path'=>$path_phpsrc.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname'])),'content'=>$_POST['file_content']);

wird:
PHP:
$att[] = array('path'=>$path_phpsrc.'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['Dir'])).'/'.preg_replace('/\s+|\/+/','',strtolower($_POST['fname'])),'content'=>str_replace(chr(13),'',stripslashes($_POST['file_content'])));

Und auf einmal sind die ^M's und die backslashes verschwunden...:eek:

Grüße

Wizjos
Ähm ein stripslashes() ohne vorherige Prüfung ob die magic_quotes auch wirklich an sind kann tödlich enden. Wenn schon solltest du erst prüfen ob magic_quotes überhaupt an sind und nur dann ein stripslashes() drüber lassen. Am einfachsten ist es aber die magic_quotes gleich in der php.ini auf OFF zu setzen und den Webserver neuzustarten. Dann hast du solche Probleme generell abgeschaltet. Sonst müsstest du den stripslashes in allen 3rd Party Scripten machen, wo Usereingaben verarbeitet werden. Drum nochmals in Kürze: magic_quotes in der php.ini deaktivieren macht viel mehr Sinn und ist auch nicht so Fehleranfällig ;)

@all
Den aktuellsten Code stelle ich heute mal nach der Arbeit hier rein. Dürfte aber der sein, den ich als letzten komplett gepostet habe
@Tok_Tok
Jop einen Wiki Eintrag könnte ich machen. Nur die kurze Frage: Im Wiki habt ihr kein Code Highlightning für PHP? Oder habe ich das nur ned gefunden? Falls ned: @ admin schaut euch mal Geshi an (perfektes Teil für ein Codewiki)

Gruss

tobi

p.s. die Börsen crashen drum muss ich wieder arbeiten ;)
 
Danke für deinen Tipp jahlives. Ich hab's sofort angepasst!:o

Grüße

Wizjos
 
Status
Für weitere Antworten geschlossen.
 

Kaffeautomat

Wenn du das Forum hilfreich findest oder uns unterstützen möchtest, dann gib uns doch einfach einen Kaffee aus.

Als Dankeschön schalten wir deinen Account werbefrei.

:coffee:

Hier gehts zum Kaffeeautomat