php

  • PHP: mysql2epub, mit PHP ePub on the fly erstellen

    Schon lange habe ich ein Buch, welches ich einmal von einer Seite gerippt habe in meiner MYSQL Datenbank abgelegt. Da es nun ein eReader in unserem Haus gibt, wollte ich das Buch wieder zurück konvertieren, damit man es auf dem eReader lesen kann. Doch wie bringt man Inhalt aus einer Datenbank in ein ePub Format? Zu meinem Erstaunen war das ganz einfach. Ein paar Kniffe gibt es aber schon. Deshalb möchte ich nun dieses kleine PHP Programm mit allen Teilen. Es darf selbstverständlich abgeändert und weiterverwendet werden und kann auch als Einstieg in die ePub Programmierung dienen. Informationen und Wissen habe ich von folgender Webseite. Sie ist zwar komplex aber komplett:
    http://www.idpf.org/doc_library/epub/OPS_2.0.1_draft.htm
    Das ganze PHP Script zum konvertieren von MYSQL nach ePub ist unten im Anhang.
    Bei Fragen und Anregungen bitte unten kommentieren, ich freue mich auf ein Feedback!

    AnhangGröße
    mysql2epub.zip7.95 KB
  • Drupal: CSS Aggregation im Private Mode

    Hat man keine Kapazitätsprobleme, kann man mit diesem Kleinen Modul die CSS optimieren, vereinigen und Cachen. Leider ist dies ansonsten in Drupal 6 Core nicht möglich. Ich weiss, der Cache braucht relativ viel Platz in der DB, aber dies ist in meinem Fall kein Problem. Das Modul erstellt für jede Seite, welche eine andere CSS Dateien Konstellation hat, ein eigener Cache-Eintrag. Die Geschwindigkeit zum Laden der Seite ist bei mir extrem gestiegen (> 33%). Anregungen bitte im Kommentar posten!

    1. // die Folgenden Konstanten anpassen
    2. define('MINICSSDPATH', '/var/www/vhosts/yourhost/httpdocs');
    3. define('MINICSSCACHE', true);
    4.  
    5.  
    6. function minicss_menu() {
    7. $items = array();
    8. $items['minicss/css'] = array(
    9. 'title' => 'minicss css',
    10. 'page callback' => 'minicss_minify',
    11. 'page arguments' => array(2,'css'),
    12. 'access callback' => true,
    13. 'type' => MENU_CALLBACK,
    14. );
    15. return $items;
    16. }
    17.  
    18. /**
    19.  * Implementation of hook_preprocess_page()
    20.  */
    21. function minicss_preprocess_page(&$variables) {
    22. if (!empty($variables['styles'])) {
    23. preg_match_all('|href="(.*?\.css)|', $variables['styles'], $matches1);
    24. $variables['styles'] = '<link type="text/css" '.
    25. 'rel="stylesheet" media="all" '.
    26. 'href="/minicss/css/'.
    27. base64_encode(implode(',',$matches1[1])).'" />';
    28. }
    29. }
    30.  
    31. function minicss_minify($files,$type) {
    32. header('Content-Type: text/'.$type);
    33. header('Cache-control: public');
    34.  
    35. // The Checksum identifies the unique css-File-Package
    36. $checksum = md5($files);
    37. // Recive Cached CSS-Package
    38. $cache = cache_get('minicss_'.$checksum);
    39. // If Package does not exist, create it and output
    40. if (!$cache) {
    41. $output = '';
    42. $files = explode(',',base64_decode($files));
    43. foreach ($files as $file) {
    44. $content = file_get_contents(MINICSSDPATH.$file);
    45. // remove comments
    46. $content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content);
    47. //$content = str_replace("\t", ' ', $content); // Removing Tabs somehow creates problems...
    48. // Remove special chars
    49. $content = str_replace(array("\r\n", "\r", "\n", ' ', ' ', ' '), '', $content);
    50.  
    51. // urls sind relativ zum CSS file und müssen dementsprechend relativ zum miniCSS angepasst werden
    52. $path = str_replace(array_pop(explode('/',$file)), '', $file);
    53. $content = str_replace('url(', 'url('.$path,$content);
    54. $output .= $content;
    55. }
    56. // Write new created Package into Cache for next time
    57. if (MINICSSCACHE) cache_set('minicss_'.$checksum,$output);
    58. header ("Content-Length: " . strlen($output));
    59. print $output;
    60. }
    61. else {
    62. // If Cache-package already exists, output cache, also add Information about version
    63. $output = '/* Retrieved from Cache; Version: '.date('Y.m.d H:i',$cache->created).' */'."\n\n".$cache->data;
    64. header ("Content-Length: " . strlen($output));
    65. print($output);
    66. }
    67. }

    Evtl. muss man in der Datenbank Tabelle "System" das Modul-weight noch an den Schluss setzen.

  • Apache/PHP: Sendmail funktioniert nicht

    Wenn man auf Debian LAMP selber installiert, dann habe ich bemerkt, dass Email in PHP versenden nicht automatisch funktioniert. Zuerst sollte man nicht vergessen, in der php.ini den Pfad zu sendmail anzugeben. Doch das alleine funktioniert noch nicht, da sendmail so eingestellt ist, dass es nur Server intern Mails versenden kann. Sämtliche Mails nach aussen werden geblockt. Mit folgendem Befehl kann man diese Einstellung ändern:

    dpkg-reconfigure exim4-config

    Man kommt in ein Konfigurationsmenü. Hier wählt man die Option "internet site; mail is sent and received directly using SMTP" und schaltet damit "local delivery only; not on a network" aus. Die weiteren Einträgen kann man lassen, bei mir habe ich noch jeweils den Host geändert. Sonst habe ich nichts verändert. Nun funktioniert der Email Versand von Drupal wieder ordentlich!

  • Subdomain weiterleiten mit Conf bzw. htaccess

    Weiterleitung einer Subdomain auf die Hauptdomain kann man direkt über das conf-File bzw über eine .htaccess Datei. Das geht folgendermassen:

    # Allen Traffic der supbdomain www.example.com und xyz.example.com weiterleiten nach example.com

    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC,OR]
    RewriteCond %{HTTP_HOST} ^xyz\.example\.com$ [NC]
    RewriteRule ^(.*)$ http://example.com$1 [R=301]

    Kann man vor allem brauchen, wenn man zwar verschiedene Subdomain anbieten möchte, jedoch nur eine Domain "promoten" möchte. Bei uns war es so, dass wir früher die Drupal Seite über eine Subdomain erreichten, jetzt direkt über die Domain. Die Leute sollen immer noch über die Subdomain draufkommen. Eine Zeit lang benutzten wir einfach einen ServerAlias. Die birgt jedoch gefahren, zB wenn man auf der Seite absolute Verweise hat. So werden nun per sofort alle Subdomain anfragen weitergeleitet.

    subdomain2domain, www2domain, www2root

  • Drupal: vCard Export

    Ich weiss, es gäbe ein Modul um Drupal Kontakte als vCard zu exportieren. Für diese einfache Aufgabe war mir dieses aber einfach viel zu schwerlastig. Also habe ich wieder einmal selber Hand angelegt und der Grössenunterschied des Modules ist beachtlich (ca 1:100!), ist nicht auf die Externe PEAR Lib angewiesen und kann mit Umlauten umgehen. vCard mit Umlauten war unter anderem der Grund, wie ich überhaupt dazu kam, es selber zu machen. Hier mein mini-Modul:

    1. function uvcard_menu() {
    2. $items = array();
    3. $items['user/%/uvcard'] = array(
    4. 'title' => t('vcard'),
    5. 'type' => MENU_CALLBACK,
    6. 'page callback' => 'uvcard_fetch',
    7. 'page arguments' => array(1),
    8. 'access arguments' => array('access content'),
    9. );
    10. return $items;
    11. }
    12.  
    13. /**
    14.  * VCard for direct download
    15.  */
    16. function uvcard_fetch($uid) {
    17. $dev = false;
    18. $eol = "\r\n";
    19. $u = user_load(array('uid' => $uid)); // gesamtes Benutzer-Profil laden
    20. $vcard = 'BEGIN:VCARD'.$eol.'VERSION:2.1'.$eol;
    21. $vcard .= 'N:'.$u->profile_nachname.';'.$u->profile_vorname.';;;'.$eol;
    22. $vcard .= 'FN;CHARSET=ISO-8859-8:'.$u->profile_vorname.' '.$u->profile_nachname.$eol;
    23. $vcard .= 'TEL;PREF;WORK;VOICE;:'.$u->profile_telefon.$eol;
    24. $vcard .= 'TEL;WORK;CELL;:'.$u->profile_telefon.$eol;
    25. $vcard .= 'TEL;WORK;FAX;:'.$u->profile_fax.$eol;
    26. $vcard .= 'EMAIL;INTERNET:'.$u->mail.$eol;
    27. $vcard .= 'ADR;DOM;WORK:;;'.$u->profile_strasse.';'.$u->profile_ort.';;'.$u->profile_plz.';'.$eol;
    28. $vcard .= 'REV'.date("Ymd\THis",$u->access).$eol;
    29. $vcard .= 'END:VCARD';
    30.  
    31. $vcard = utf8_decode($vcard);
    32.  
    33. if ($def) { print $vcard.$eof; print '<pre>'.print_r($u,1).'</pre>'; exit;}
    34. // Set headers
    35. header('Content-type: text/x-vcard');
    36. header('Content-Disposition: attachment; filename="'. $u->name .'.vcf"');
    37. print $vcard;
    38. }

    Wenn man die Variable $def nach true umstellt, bekommt man die erzeugte vCard ausgeprintet und zusätzlich das gesamte Benutzerprofil, dmait man sich die oberen Zeilen gemäss seinen eigenen Wünschen anpassen kann.
    Die vCard Spezifikationen habe ich mir von http://en.wikipedia.org/wiki/VCard geholt.
    Um die Seite aufzurufen, muss man dann nur noch irgendwo ein Link darauf machen (zB in einer View-Spalte).

  • Drupal: fid2nid, nid von fid

    Für ein Modul musste ich aus einer fid die zugehörige nid herausfinden. Bis anhin habe ich noch keine Funktion in der API gefunden, welche dies erledigt. Hier mein Vorschlag:

    1. /**
    2.  * Get's the $nid from a File of a CCK File-Field $fid
    3.  */
    4. function fid2nid($fid) {
    5. // Get all the CCK-File-Fields
    6. $fields = array();
    7. $sql = "SELECT field_name FROM {content_node_field} WHERE type LIKE 'filefield';";
    8. $result = db_query($sql);
    9. while ($r = db_fetch_array($result)) {
    10. $fields[] = $r['field_name'];
    11. }
    12. $found = false;
    13.  
    14. foreach ($fields as $field) {
    15. // Checks if the table exists
    16. $sql = "SHOW TABLES LIKE 'content_".$field."'";
    17. $result = db_query($sql);
    18. $i = false;
    19. while ($r = db_fetch_array($result)) { $i = true; }
    20. // If it does, see if fid is in this table
    21. if ($i) {
    22. $sql = "SELECT content_".$field.".nid FROM files
    23. LEFT JOIN content_".$field."
    24. ON (files.fid = content_".$field.".".$field."_fid)
    25. WHERE ".$field."_fid = '%d'";
    26. $result = db_query($sql, $fid);
    27. while ($r = db_fetch_array($result)) {
    28. $nid = $r['nid'];
    29. }
    30. if (count($nid)) {break;} // if fid is in table, stop while and return nid
    31. }
    32. }
    33. return $nid;
    34.  
    35. }

  • Eclipse vs. Netbeans für Drupal und PHP

    Seit 2 Jahren benutze ich nun auch Eclipse zum entwickeln von Drupal Modulen in PHP. Richtig überzeugen konnte mich Eclipse jedoch nie. Ich fand das Programm einfach zu schwerlastig um PHP-Code damit zu erstellen. So habe ich nun seit einer Woche Netbeans im Einsatz. Der erste Eindruck scheint gelungen. Das ganze Programm kommt viel schlanker daher. Die Installation geht schnell und PHP kann man direkt als fertige Distribution herunterladen (ähnlich wie PHPEclipse).

    Hier meine positiven Punkte:

    • schneller Start des Programmes
    • übersichtliche Oberfläche
    • Projekt-Wizard sehr gut
    • Projekte, welche auf einem entfernten Server getestet werden (via FTP) können als solche verknüpft werden, es ist also kein zusätzliches FTP Programm nötig
    • bereits nach einem Tag kenne ich mehr Funktionen des Programmes als nach 2 Jahren Eclipse
    • Plugin für Drupal
    Negatives:
    • bisher noch nichts zu bemängeln
    Achtung: Das Plugin für Drupal ist nicht aktuell. Auf der offiziellen Seite gibt es keine aktuelle Version. Ich habe aber für NetBeans 9.1 das Drupal Plugin hier gefunden -> http://hollyit.net/files/org-netbeans-modules-php-drupal-module.nbm . Es hat auch funktioniert.
    NetBeans
  • Drupal: XSend bzw mod_xsendfile auf Debian installieren

    Für Apache gibt es ein super Modul, welches den Dateitransfer massiv verschnellert, bzw die Ladezeit bis zum Dateitransfer. Das Modul heisst mod_xsendfile. Ich hatte einige Probleme das Ding auf meinem Debian zum laufen zu bringen. So habe ich es gemacht:

    1. Wechseln zum Ordner für Apache Module (/usr/lib/apache2/modules; wenn anders dann kann man den modules Ordner suchen: find / -name 'modules')
    2. Source herunterladen mit Link (Link Datei; Link Seite)
    3. apxs2 -cia mod_xsendfile.c (Achtung, bei mir musste ich eine 2 an das apxs anhängen, ist nicht so auf Homepage beschrieben!)
    4. Bei mir kam dann am Schluss folgende Fehlermeldung:
      1. apxs:Error: Activation failed for custom /etc/apache2/httpd.conf file..
        apxs:Error: At least one `LoadModule' directive already has to exist..
    5. Lösen kann man das Problem mit folgendem Trick:
      1. nano /etc/apache2/httpd.conf
      2. Die folgenden zwei Zeilen untereinander eintragen
      3. #LoadModule directive to aid module installations
        #LoadModule dummy_module /usr/lib/apache2/modules/mod_dummy.so
      4. Wieder zumachen und speichern
    6. Apache neu starten (invoke-rc.d apache2 restart)
    7. Ich bin nicht ein Fan von Core-Patches, jedoch ziehe ich in diesem Fall ein solcher vor. Anstelle des xfile Modules von Drupal reicht es (für meinen Fall) in der includes/file.inc die Funktion file_transfer mit der Zeile "$headers[] = 'X-Sendfile: '.$source;" gerade nach dem ersten if {} Konstrukt einzufügen. Das Drupal modul xfiles ist so überflüssig.
    function file_transfer($source, $headers) {
      if (ob_get_level()) {
        ob_end_clean();
      }
      $headers[] = 'X-Sendfile: '.$source; 
      foreach ($headers as $header) {
      ..
  • Drupal: PDF Vorschau als jpg, pdf2jpg, PDF Thumbnails

    Immer schon wollte ich auf Webseiten pdf's als Bilder darstellen. Sinnvolle Hilfe dazu zu finden ist meiner Meinung nach eher schwierig. Für eine aktuelle Drupal-Installation wollte ich nun endlich mal einen Schritt weitergehen und meine Wünsche in etwas Handfestes umwandeln. Im Drupal CMS sollten sämtliche PDFs auch als jpg/png automatisch zur Verfügung stehen. Dazu habe ich ein neues Modul geschrieben, ich habs Preview genannt. Ich stellte mir vor, dass es in Zukunft verschiedene Dateitypen als Preview erstellen sollte, nicht nur PDFs. Zurzeit bin ich dran, das Modul so umzugestalten, damit ich es auf drupal.org contributen kann. Auf meiner vorhanden Drupalinstallation läuft es aber breits wie geschmiert. Ich werde bei Gelegnheit mehr Details dazu posten (wird auch vom Interesse von Euch abhängen...).Mein Fazit bis jetzt: Es ist alles was ich mir je gewünscht habe. Gerade grosse PDFs (bei uns handelt es sich um Baupläne, >90MB pro Seite) müssen so nicht heruntergeladen werden sondern werden innert Kürze in der "Vorschau" angezeigt.

    screenshoots: 
    screenshot.9.png
  • Drupal: Auf fremde/zweit Datenbank zugreifen

    Problem: Auf der vorhanden Drupal Installation will ich auf Daten einer anderen Datenbank zugreifen. Drupal hat dafür bereits einen Weg vorgesehen. Dazu geht man in die sites/default/settings.php Datei. Folgende Zeile definiert die Standard Datenbank:

    $db_url 'mysql://drupal:drupal@localhost/drupal';

    Wandelt man $db_url in ein Array um, kann man beliebig viele Datenbank definieren.:

    $db_url['default'] ='mysql://drupal:drupal@localhost/drupal';
    $db_url['mydb'] = 'mysql://user:pwd@localhost/anotherdb';
    $db_url['db3'] ='mysql://user:pwd@localhost/yetanotherdb';

    Im Modul, wo man dann auf die Daten zugreifen will mach man das folderndermassen:

    db_set_active('mydb');

    db_query('SELECT * FROM table_in_anotherdb');

    //...
    db_set_active('default');

    Default ist die Standard-Datenbank. Sie ist erforderlich. In dieser Datenbank ist Drupal installiert. Man muss aufpassen, dass man nach dem Sprung in die andere Datenbank die default Datenbank wieder auf aktiv stellt.

    Quelle: http://drupal.org/node/18429

Inhalt abgleichen