iPhone sync ohne Google Sync

Ich habe gestern hier gelesen, dass bei Google Sync (Active Sync. mit Gmail), zum 30.01.2013 für neue Nutzer abgeschaltet wird und dann nur noch mit den kostenpflichtigen Accounts möglich ist.

Deshalb habe ich mir mal angesehen (obwohl ich nicht betroffen sein sollte), wie ich weiterhin mein iPhone/iPad Synchronisieren kann.

Dabei musste ich feststellen, dass es eigentlich ganz einfach einzurichten ist und sogar einige Probleme behebt.

Zum Synchronisieren von Mail, Kalender und Notizen (ging mit Goggle Sync nicht) bedarf es nichts weiter als beim Hinzufügen eines Accounts, Gmail auszuwählen und seine Login Daten zu hinterlegen. Einziger Nachteil den ich bisher gefunden habe, ist, dass die Gmail Adresse auch gleichzeitig die Absenderadresse ist. Die Synchronisation wird dann per IMAP mit dem Gmail Konto durchgeführt. Der Kalender wird per CalDAV synchronisiert und die Notizen landen im IMAP Ordner Notes. Den Nachteil mit den Absenderadresse umgehe ich, indem ich die Gmail App installiert habe und diese zum Mailen verwende. Die App nutzt auch die Signaturen, die man in seinen Gmail Konto eingerichtet hat und man kann mit den liebgewonnen Labels vernünftig arbeiten. Dadurch, dass ich jetzt beides eingerichtet habe, kann ich zur Not auch noch direkt aus einer anderen App eine Mail verschicken. Ein weiterer Vorteil ist, dass man direkt alle seine Google Kalender zur Verfügung hat und diese nicht erst über eine extra Internetseite freischalten muss. Den Geburtstagskalender vom Google Kalender habe ich allerdings abgewählt, da ich nicht alle Geburtstage doppelt haben wollte.

Die Kontakte Synchronisation muss man, ich denke zurzeit noch, extra einrichten. Dazu richtet man ein zusätzlichen Account für CardDAV ein. Der Server Name ist google.com, plus die Google Account Daten. Damit geht dann auch die Synchronisation der Kontakte. Im Moment sieht es so aus als würde das auch besser funktionieren als mit Google Sync (Active Snyc.) zumindest scheint es so, dass sich die Felder in den Adressen nicht mehr wahrlos umbenennen und ich hoffe, dass Geburtstage sich nicht mehr verschieben.

Alles in allem scheint es keinen Nachteil durch das „abschalten“ von Google Sync zu geben und man braucht auch keine extra Sync. Software zu installieren.

iPhone Google Sync einrichten

Mal wieder einige der Dinge, die ich öfter wiedersuche. Wie richte ich mein iPhone mit Google Sync. (Exchange Aktive Sync.) ein.

Das wird auf der Seite http://support.google.com/mail/bin/answer.py?hl=de&answer=138740&topic=21161&ctx=topic sehr gut beschrieben.

Was aber wichtig zu wissen ist, dass man auch mehrere Kalender synchronisieren kann und auch einstellen kann, welche die Standard Absender Adresse ist. Wo man das macht, ist hier beschrieben: http://support.google.com/mobile/bin/answer.py?hl=en&answer=139206
Wichtig ist dabei die Sprache auf Englisch (US) umzustellen.

Die Punkte im Einzelnen:

  • ‚Enable „Send Mail As“ for this device‘. Bedeutet, dass der Standard Absender aus dem Gmail Account genommen wird.
  • ‚Enable „Delete Email As Trash“ for this device‘. Bedeutet, dass wenn man Mails löscht, diese nicht archiviert werden, sondern wirklich gelöscht werden (im Papierkorb landen).
  • Dann kann man noch einstellen, welche Kalender man synchronisieren möchte.

WordPress Links Menü Walker

Hier eine kleine Walker Klasse für WordPress, um sich ein Menü in der Form “ Link1 | Link2 | Link3 “ zu erstellen.

Einfach die Klasse in die functions.php des Themes und den Menü Eintrag dort im Template platzieren, wo er hin soll.

<?php
wp_nav_menu(
   array(
      'container'      => FALSE,
      'menu'           => 'The Footer Links',
      'menu_class'     => 'nav',
      'theme_location' => 'footer-nav',
      'items_wrap'     => '<nav id="%1$s" class="%2$s" role="navigation">%3$s</nav>',
      'depth'          => 1,
      'walker'         => new Links_Walker_Nav_Menu()
   )
);

class Links_Walker_Nav_Menu extends Walker_Nav_Menu {

   function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

      //Add attributes to link element.
      $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) . '"' : '';
      $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) . '"' : '';
      $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) . '"' : '';
      $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
      $attributes .= ( $item->current ) ? ' class="active"' : '';

      $output .= ( $item->menu_order > 1 ) ? ' | ' : '';
      $output .= '<a' . $attributes . '>';
      $output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
      $output .= '</a>';

   }

   function end_el( &$output, $item, $depth = 0, $args = array() ) {

      $output .= '';
   }

}

Standard WordPress Plugin Funktionen

Zwei der Funktionen/Methoden, die man in Zukunft wohl in allen meinen Plugins finden wird, sind:
Voraussetzung ist PHP 5.1.2 für die Autoload Funktion.

1. Zum Ermitteln von Plugin Daten, damit nicht immer alles per Constante definiert wird, um Namensraum freizuhalten:

<?php
public static function get_plugin_data( $get_data = FALSE ) {

	$plugin_data = wp_cache_get( 'plugin_data', 'pluginname' );
	if ( $plugin_data === FALSE || empty( $plugin_data[ 'Version' ] ) ) {
		$plugin_data               = get_file_data(
			__FILE__, array(
				'Name'        => 'Plugin Name',
				'PluginURI'   => 'Plugin URI',
				'Version'     => 'Version',
				'Description' => 'Description',
				'Author'      => 'Author',
				'AuthorURI'   => 'Author URI',
				'TextDomain'  => 'Text Domain',
				'DomainPath'  => 'Domain Path'
			), 'plugin'
		);
		$plugin_data[ 'BaseName' ] = plugin_basename( __FILE__ );
		$plugin_data[ 'Folder' ]   = dirname( plugin_basename( __FILE__ ) );
		$plugin_data[ 'URL' ]      = plugins_url( '', __FILE__ );
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
			$plugin_data[ 'JSVersion' ] = time();
		} else {
			$plugin_data[ 'JSVersion' ] = $plugin_data[ 'Version' ];
		}
		wp_cache_add( 'plugin_data', $plugin_data, 'pluginname' );
	}

	if ( ! $get_data ) {
		return $plugin_data;
	}

	return $plugin_data[ $get_data ];
}

2. Die Autoload Funktion von PHP zum automatischen Laden von Klassen, damit sie nur dann geladen werden, wenn sie auch benötigt werden. Das heißt, verwendet man ein „add_action“ wird die Klasse erst geladen, wenn wirklich ein „do_action“ erfolgt oder die Seitenklasse für einen Menüeintrag erst geladen wird, wenn der Menüpunkt tatsächlich aufgerufen wird. Voraussetzung ist, dass man das ganze Plugin klassenbasierend aufbaut. Das kann dann nicht nur Ressourcen sparen.

<?php
public function __construct() {
	//register autoloader
	spl_autoload_register( array( $this, 'autoloader' ) );
}

public static function autoloader( $class_name ) {
	//WordPress classes loader
	$wpclass='/class-'.strtolower(str_replace('_','-',$class_name)).'.php';
	if ( is_file(ABSPATH .'wp-admin'.DIRECTORY_SEPARATOR.'includes'.$wpclass) ) {
		require(ABSPATH .'wp-admin'.DIRECTORY_SEPARATOR.'includes'.$wpclass);
		return true;
	}
	if ( is_file(ABSPATH . WPINC . $wpclass) ) {
		require(ABSPATH . WPINC . $wpclass);
		return true;
	}

	//Plugin classes to load
	if ( strpos( $class_name,'PluginClass_') !== false ) {
		$class_load = dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'inc'.DIRECTORY_SEPARATOR.'class-' . strtolower( str_replace( array( 'PluginClass_', '_' ), array( '', '-' ), $class_name ) ) . '.php';
		if ( is_file( $class_load ) ) {
			require($class_load);
			return true;
		}

	}
	return false;
}

Diese sollten sich innerhalb der Haupt Plugin Datei in einer Klasse befinden.

PHP Verzeichnis Übergabe prüfen

Ich muss in meinem Plugin für WordPress den ABSPATH übergeben, um eine eigene Ajax Behandlung zu haben.
Was meint ihr ist der Codeschnipsel dafür geeignet, um es möglicht sicher gegen Angriffe zu machen?

<?php
if ( is_file( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-load.php' ) ) {
	require_once( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-load.php' );
} else {
	$abspath = filter_input( INPUT_POST, 'ABSPATH', FILTER_SANITIZE_URL );
	$abspath = rtrim( realpath( $abspath ), '/' );
	if ( ! empty( $abspath ) && is_dir( $abspath . '/' ) && is_file( realpath( $abspath . '/wp-load.php' ) ) ) {
		require_once( $abspath . '/wp-load.php' );
	} else {
		die();
	}
}

Erläuterung:
Wenn der Plugins Ordner im Standard Verzeichnis ist oder zumindest in der selben Verzeichnis Tiefe muss die Übergabe nicht genutzt werden.
Sonst.
Das übergebene Verzeichnis vorfiltern (nur in URLs erlaubte Zeichen werden zugelassen)
mit ‚realpath()‘ alle ‚../‘,‘./‘ entfernen und prüfen, ob das Verzeichnis existiert.
Da ‚realpath()‘ auch das aktuelle Verzeichnis ausgibt nochmal Verzeichnis und Datei auf Existenz prüfen.
WP-load.php laden.

Ressourcen sparen bei Ajax Calls in WordPress

Bei meiner Arbeit am Plugin BackWPup habe ich nach einer Möglichkeit gesucht Ressourcen bei Ajax Calls und bei der Auftragsausführung zu sparen. Die einzige große Einsparung, die ich bisher gefunden habe, ist es die Übersetzungen anderer Plugins nicht mit zu laden, da die enorm viel Speicher verbrauchen. Dies bringt in meiner Testinstallation mit 20 Plugins eine Einsparung von 31 MB auf 25,5 MB Script Speicher. Da die Dateien auch nicht geöffnet werden, wird das auch noch eine Einsparung bringen, die ich im Moment nicht beziffern kann.

Hier die Umsetzung:
Wichtig ist hierbei, dass ich nur die Übersetzungen nicht lade, wenn es sich um Calls meines Plugins handelt.

<?php
define( 'PLUGIN_MENU_PAGES', 'page1,page2' );
if ( defined( 'DOING_AJAX' ) and DOING_AJAX and in_array(
		$_POST[ 'backwpupajaxpage' ], explode( ',', PLUGIN_MENU_PAGES )
	)
) {
	add_filter(
		'override_load_textdomain', create_function(
			'$default, $domain, $mofile', 'if ($domain=="textdomain") return $default; else return true;'
		), 1, 3
	);
}

Zusätzlich musste ich noch einbauen, dass mein Plugin als erstes geladen wird:

<?php
define( 'PLGUNINNAME_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

public function pluginname_first_plugin( $newvalue, $oldvalue ) {

	if ( ! is_array( $newvalue ) ) {
		return $newvalue;
	}
	for ( $i = 0; $i < count( $newvalue ); $i++ ) {
		if ( $newvalue[ $i ] == PLGUNINNAME_PLUGIN_BASENAME ) {
			unset( $newvalue[ $i ] );
		}
	}
	array_unshift( $newvalue, PLGUNINNAME_PLUGIN_BASENAME );

	return $newvalue;
}

add_filter( 'pre_update_option_active_plugins', 'pluginname_first_plugin', 1, 2 );

Vielleicht kennt ja noch jemand eine Lösung die Ressourcen weiter zu optimieren und die WordPress eigene Ajax Behandlung zu nutzen…

Update:
mit einer etwas geänderten Funktion ist es nicht mehr notwendig das Plugin nach vorne zu schieben.

<?php
define( 'PLUGIN_MENU_PAGES', 'page1,page2' );
function overide_textdomain( $default, $domain, $mofile ) {

	if ( ( defined( 'DOING_CRON' ) && DOING_CRON )
		&& in_array(
			$_POST[ 'backwpupajaxpage' ], explode( ',', PLUGIN_MENU_PAGES )
		)
	) {
		global $l10n;
		if ( $domain == 'owntextdomainname' ) {
			foreach ( array_keys( $l10n ) as $domainkey ) {
				unset( $l10n[ $domainkey ] );
			}
		} else {
			return TRUE;
		}
	}

	return $default;
}

add_filter( 'override_load_textdomain', 'overide_textdomain' );

Update: Ich glaub das beste ist es, wenn in WordPress der WP-Performance-Gettext-Patch integriert wird. Nach meinen Tests bringt das am meisten. Der Speicherverbrauch geht dann auf ca. 17MB runter.

WordPress 3.3 add_contextual_help deprecated

Eine einfache Möglichkeit festzustellen, ob man mit „add_contextual_help()“ oder „get_current_screen()->add_help_tab“ arbeiten muss, um die abwärts Kompatibilität zu behalten.

<?php
if (method_exists(get_current_screen(),'add_help_tab')) {
    get_current_screen()->add_help_tab( array(
        'id' => 'plugininfo',
        'title' => 'Plugin Info',
        'content' => 'Text') );
} elseif (function_exists('add_contextual_help')) {
    add_contextual_help( get_current_screen(), 'Text');
}