[merged]
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Wed, 26 Oct 2011 21:44:35 +0200
changeset 18 846026b8422b
parent 17 56308e61381c (diff)
parent 16 152fc2237f2d (current diff)
child 19 326bed5a9677
[merged]
addressbook.class.php
class.Address_Book_DB.php
class.Address_Book_File.php
index.php
--- a/.hgignore	Wed Oct 26 16:28:42 2011 +0200
+++ b/.hgignore	Wed Oct 26 21:44:35 2011 +0200
@@ -3,3 +3,8 @@
 var/abook.txt
 .index.php.swp
 var/abook.txt~
+class.Address_Book_DB.php~
+class.Address_Book_File.php~
+templates/results.html~
+test.php~
+var/abook.sqlite
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/_vimrc	Wed Oct 26 21:44:35 2011 +0200
@@ -0,0 +1,67 @@
+version 6.0
+if &cp | set nocp | endif
+let s:cpo_save=&cpo
+set cpo&vim
+cnoremap <C-F4> c
+inoremap <C-F4> c
+cnoremap <C-Tab> w
+inoremap <C-Tab> w
+cmap <S-Insert> +
+imap <S-Insert> 
+xnoremap  ggVG
+snoremap  gggHG
+onoremap  gggHG
+nnoremap  gggHG
+vnoremap  "+y
+noremap  
+vnoremap  :update
+nnoremap  :update
+onoremap  :update
+nmap  "+gP
+omap  "+gP
+vnoremap  "+x
+noremap  
+noremap  u
+cnoremap   :simalt ~
+inoremap   :simalt ~
+map Q gq
+nmap gx <Plug>NetrwBrowseX
+nnoremap <silent> <Plug>NetrwBrowseX :call netrw#NetrwBrowseX(expand("<cWORD>"),0)
+onoremap <C-F4> c
+nnoremap <C-F4> c
+vnoremap <C-F4> c
+onoremap <C-Tab> w
+nnoremap <C-Tab> w
+vnoremap <C-Tab> w
+vmap <S-Insert> 
+vnoremap <BS> d
+vmap <C-Del> "*d
+vnoremap <S-Del> "+x
+vnoremap <C-Insert> "+y
+nmap <S-Insert> "+gP
+omap <S-Insert> "+gP
+cnoremap  gggHG
+inoremap  gggHG
+inoremap  :update
+inoremap  u
+cmap  +
+inoremap  
+inoremap  u
+noremap   :simalt ~
+let &cpo=s:cpo_save
+unlet s:cpo_save
+set backspace=indent,eol,start
+set backup
+set diffexpr=MyDiff()
+set guifont=Lucida_Sans_Typewriter:h14:cANSI
+set helplang=de
+set history=50
+set hlsearch
+set incsearch
+set keymodel=startsel,stopsel
+set ruler
+set selection=exclusive
+set selectmode=mouse,key
+set whichwrap=b,s,<,>,[,]
+set window=33
+" vim: set ft=vim :
--- a/addressbook.class.php	Wed Oct 26 16:28:42 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-<?
-
-interface Address_Book {
-    public function get_entries();
-    public function search_entries($pattern);
-    public function add_entry($entry);
-}
-
-class Address_Book_Exception extends Exception { }
-
-class Address_Book_File implements Address_Book {
-
-    const RS = "\n";
-    const FS = "\t";
-
-    private $fh;
-    private $file;
-
-    function __construct($file) {
-	@mkdir(dirname($file));
-	$this->fh = fopen($file, "a+b");
-	flock($this->fh, LOCK_EX);
-	$stat = fstat($this->fh);
-	if ($stat['size'] == 0) {
-		fputs($this->fh, join(self::FS, array("Hans Hanson", "0815", "hans@hanson.de"))
-			. self::RS);
-	}
-	flock($this->fh, LOCK_SH);
-	fseek($this->fh, 0, SEEK_SET);
-    }
-
-    function get_entries() {
-	$entries = array();
-	fseek($this->fh, 0, SEEK_SET);
-	while($line = stream_get_line($this->fh, 0, self::RS)) {
-		if ($line === FALSE) break;
-		$entries[] = explode(self::FS, $line);
-	}
-	return $entries;
-    }
-
-    function add_entry($entry) {
-	$fields = array('name', 'tel', 'mail');
-
-	$new = array();
-	foreach($fields as $key) {
-		if (!isset($entry[$key])) return false;
-		$new[$key] = trim($entry[$key]);
-		$new[$key] = preg_replace('/['.self::RS.self::FS.' ]+/', ' ', $new[$key]);
-		if (empty($new[$key])) return false;
-	}
-
-	flock($this->fh, LOCK_EX);
-	fputs($this->fh, join(self::FS, $new) . self::RS);
-	flock($this->fh, LOCK_UN);
-
-	return true;
-    }
-
-    function search_entries($pattern) {
-	$pattern = trim($pattern);
-	if (empty($pattern)) return;
-	//$pattern = preg_replace('/\//', '\/', $pattern);
-	if (preg_match('/\//', $pattern))
-	    throw new Address_Book_Exception("Pattern must not contain '/'");
-	fseek($this->fh, 0, SEEK_SET);
-	$entries = array();
-	while ($line = stream_get_line($this->fh, 0, self::RS)) {
-		if ($line === FALSE) break;
-		if (!preg_match("/$pattern/i", $line)) continue;
-		$entry = explode(self::FS, $line);
-		$entries[] = array('name' => $entry[0],
-			           'tel' => $entry[1],
-				   'mail' => $entry[2]);
-	}
-	return $entries;
-    }
-}
-
-?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/class.Address_Book_DB.php	Wed Oct 26 21:44:35 2011 +0200
@@ -0,0 +1,99 @@
+<?
+require_once "interface.Address_Book.php";
+
+class Address_Book_DB implements Address_Book {
+	const INSERT_ENTRY = 'INSERT INTO data (name, tel, mail)
+	 		      VALUES(:name, :tel, :mail)';
+	const SELECT_ENTRY = 'SELECT name AS NAME, tel AS TEL, mail AS MAIL
+			      FROM data WHERE name LIKE :name
+			      	           OR tel LIKE :tel
+					   OR mail LIKE :mail';
+		
+
+	private $dbh;
+
+	public function __construct($dsn, $user = null, $pass = null) {
+		$this->dbh = new PDO($dsn, $user, $pass,
+		array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
+
+		$this->dbh->exec("CREATE TABLE IF NOT EXISTS data
+			(name TEXT, tel TEXT, mail TEXT)");
+
+		$this->dbh->beginTransaction();
+
+		$sth = $this->dbh->prepare("SELECT COUNT(*) AS COUNT FROM data");
+		$sth->execute();
+		$r = $sth->fetch();
+
+		if ($r['COUNT'] == 0) 
+			$this->insert(array("Hans Hanson", "0815", "hans@hanson.de"));
+		$this->dbh->commit();
+	}
+
+	private function insert($entry) {
+		static $sth = null;
+
+		if ($sth === null)
+			$sth = $this->dbh->prepare(self::INSERT_ENTRY);
+		
+		$sth->execute(array("name" => $entry[0],
+				    "tel"  => $entry[1],
+				    "mail" => $entry[2]));
+	}
+			
+	public function get_all_entries() {
+		$entries = array();
+		fseek($this->fh, 0, SEEK_SET);
+		while($line = stream_get_line($this->fh, 0, self::RS)) {
+			if ($line === FALSE) break;
+			$entries[] = explode(self::FS, $line);
+		}
+		return $entries;
+	}
+
+	public function add_entry($entry) {
+		$fields = array('name', 'tel', 'mail');
+		$new = array();
+		foreach($fields as $key) {
+			if (!isset($entry[$key])) return;
+			$new[$key] = $entry[$key];
+			trim($new[$key]);
+			preg_replace('/['.self::RS.self::FS.' ]+/', ' ', $new[$key]);
+			if (empty($new[$key])) return;
+		}
+
+		flock($this->fh, LOCK_EX);
+		fputs($this->fh, join(self::FS, $new) . self::RS);
+		flock($this->fh, LOCK_UN);
+		header("Location: $_SERVER[PHP_SELF]?action=add");
+		exit;
+	}
+
+	public function search_entries($pattern) {
+		static $sth = null;
+
+		if ($sth === null)
+			$sth = $this->dbh->prepare(self::SELECT_ENTRY);
+
+		$pattern = trim($pattern);
+		if (empty($pattern)) return;
+
+		$pattern = trim($pattern, '%');
+		$pattern = "%$pattern%";
+
+		$sth->execute(array("name" => $pattern,
+				    "tel" => $pattern,
+				    "mail" => $pattern));
+		$entries = array();
+		while ($r = $sth->fetch()) {
+			$entries[] = array('name' => $r['NAME'],
+					   'tel' => $r['TEL'],
+					   'mail' => $r['MAIL']);
+		}
+		return $entries;
+	}
+
+	public function delete_entries($ids) { }
+}
+
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/class.Address_Book_File.php	Wed Oct 26 21:44:35 2011 +0200
@@ -0,0 +1,70 @@
+<?
+require_once "interface.Address_Book.php";
+
+class Address_Book_File implements Address_Book {
+	const RS = "\n";
+	const FS = "\t";
+
+	private $fh;
+	public function __construct($file) {
+		@mkdir(dirname($file));
+		$this->fh = fopen($file, "a+b");
+		if (!$this->fh) {
+			throw new Exception("Oooops, Problem mit $file");
+		}
+		flock($this->fh, LOCK_EX);
+		$stat = fstat($this->fh);
+		if ($stat['size'] == 0) {
+			fputs($this->fh, join(self::FS, array("Hans Hanson", "0815", "hans@hanson.de"))
+				. self::RS);
+		}
+		flock($this->fh, LOCK_SH);
+		fseek($this->fh, 0, SEEK_SET);
+	}
+
+	public function get_all_entries() {
+		$entries = array();
+		fseek($this->fh, 0, SEEK_SET);
+		while($line = stream_get_line($this->fh, 0, self::RS)) {
+			if ($line === FALSE) break;
+			$entries[] = explode(self::FS, $line);
+		}
+		return $entries;
+	}
+
+	public function add_entry($entry) {
+		$fields = array('name', 'tel', 'mail');
+		$new = array();
+		foreach($fields as $key) {
+			if (!isset($entry[$key])) return;
+			$new[$key] = trim($entry[$key]);
+			$new[$key] = preg_replace('/['.self::RS.self::FS.' ]+/', ' ', $new[$key]);
+			if (empty($new[$key])) return;
+		}
+
+		flock($this->fh, LOCK_EX);
+		fputs($this->fh, join(self::FS, $new) . self::RS);
+		flock($this->fh, LOCK_UN);
+	}
+
+	public function search_entries($pattern) {
+		$pattern = trim($pattern);
+		if (empty($pattern)) return array();
+		fseek($this->fh, 0, SEEK_SET);
+		$pattern = preg_replace('|/|', '\/', $pattern);
+		$entries = array();
+		while ($line = stream_get_line($this->fh, 0, self::RS)) {
+			if ($line === FALSE) break;
+			if (!preg_match("/$pattern/i", $line)) continue;
+			$entry = explode(self::FS, $line);
+			$entries[] = array('name' => $entry[0],
+					   'tel' => $entry[1],
+					   'mail' => $entry[2]);
+		}
+		return $entries;
+	}
+
+	public function delete_entries($ids) { }
+}
+
+?>
--- a/index.php	Wed Oct 26 16:28:42 2011 +0200
+++ b/index.php	Wed Oct 26 21:44:35 2011 +0200
@@ -1,75 +1,83 @@
-<?php
-// Template Engine
-require_once 'Twig-1.3.0/lib/Twig/Autoloader.php';
-Twig_Autoloader::register();
-$twig = new Twig_Environment(new Twig_Loader_Filesystem("templates"));
-
-const FILE = "var/abook.txt";
-
-// stop on any error!
-set_error_handler(create_function('$a, $b, $c, $d', 
-    'if (error_reporting()) throw new ErrorException($b, 0, $a, $c, $d);'), -1);
-
-if (isset($_REQUEST['action'])) {
-    require 'addressbook.class.php';
-
-    try {
-	$abook = new Address_Book_File(FILE);
-
-	switch (@$_REQUEST['action']) {
-		// Nach dem Eintragen bleiben wir auf der Eintragsseite,
-		// aber wir verhindern Duplikate, die mit RELOAD passieren
-		case 'add':	if ($abook->add_entry($_REQUEST)) {
-				    header("Location: $_SERVER[PHP_SELF]?action=add");
-				    exit(0);
-			    }
-			    echo $twig->render("add.html", array());
-			    exit;
-			    break;
-
-		// Suchen…
-		case 'search':  $entries = null;
-				$error = null;
-				try {
-				    $entries = $abook->search_entries($_REQUEST['pattern']);
-				}
-				catch (Address_Book_Exception $e) {
-				    $error = $e->getMessage();
-				}
-
-				if (@$_REQUEST['format'] == 'table') {
-				    if (is_numeric($_REQUEST['max'])) {
-					$left = count($entries) - $_REQUEST['max'];
-					if ($left > 0) 
-					    $entries = array_slice($entries, 0, $_REQUEST['max']);
-					else
-					    $left = NULL;
-				    }
-				    echo $twig->render("results.html",
-					array('entries' => $entries,
-					'left' => $left, 'error' => $error));
-				    exit;
-				}
-				echo $twig->render("search.html",
-				    array('entries' => $entries, 'error' => $error));
-				exit;
-			    }
-			    break;
-
-    }
-    catch (Address_Book_Exception $e) {
-	header("Content-Type: text/plain; charset=utf-8");
-	print "Address Book Exception: " . $e->getMessage();
-	exit;
-    }
-    catch (Exception $e) {
-	header("Content-Type: text/plain; charset=utf-8");
-	print "Ohoh\n\n" . $e;
-	exit;
-    }
-}
-
-echo $twig->render("search.html", array());
-
-exit;
-?>
+<?php
+
+const FILE = "var/abook.txt";
+const DB = "sqlite:var/abook.sqlite";
+const ABOOK = DB;	
+
+set_error_handler(create_function(
+	'$errno, $errstr, $errfile, $errline, $errcontext',
+	'if (!error_reporting()) return;
+	throw new ErrorException($errstr, 0, $errno, $errfile, $errline);'), -1);
+
+spl_autoload_register(create_function(
+    '$class',
+    '$file = "class.$class.php";
+     if (!file_exists($file)) return;
+     require_once $file;'));
+
+require_once 'Twig-1.3.0/lib/Twig/Autoloader.php';
+Twig_Autoloader::register();
+$twig = new Twig_Environment(new Twig_Loader_Filesystem("templates"));
+
+if (isset($_REQUEST['action'])) {
+
+    try {
+	if (preg_match('/^[\w]+\//', ABOOK))
+	    $abook = new Address_Book_File(FILE);
+	else 
+	    $abook = new Address_Book_DB(DB);
+
+	switch (@$_REQUEST['action']) {
+		// Nach dem Eintragen bleiben wir auf der Eintragsseite,
+		// aber wir verhindern Duplikate, die mit RELOAD passieren
+		case 'add':	if ($abook->add_entry($_REQUEST)) {
+				    header("Location: $_SERVER[PHP_SELF]?action=add");
+				    exit(0);
+			    }
+			    echo $twig->render("add.html", array());
+			    exit;
+			    break;
+
+		// Suchen…
+		case 'search':  $entries = null;
+				$error = null;
+				try {
+				    $entries = $abook->search_entries($_REQUEST['pattern']);
+				}
+				catch (Address_Book_Exception $e) {
+				    $error = $e->getMessage();
+				}
+
+				if (@$_REQUEST['format'] == 'table') {
+				    if (is_numeric($_REQUEST['max'])) {
+					$left = count($entries) - $_REQUEST['max'];
+					if ($left > 0) 
+					    $entries = array_slice($entries, 0, $_REQUEST['max']);
+					else
+					    $left = NULL;
+				    }
+				    echo $twig->render("results.html",
+					array('entries' => $entries,
+					'left' => $left, 'error' => $error));
+				    exit;
+				}
+				echo $twig->render("search.html",
+				    array('entries' => $entries, 'error' => $error));
+				exit;
+			    }
+			    break;
+
+    }
+    catch (Address_Book_Exception $e) {
+	header("Content-Type: text/plain; charset=utf-8");
+	print "Address Book Exception: " . $e->getMessage();
+	exit;
+    }
+    catch (Exception $e) {
+	header("Content-Type: text/plain; charset=utf-8");
+	print "Ohoh\n\n" . $e;
+	exit;
+    }
+}
+
+echo $twig->render("search.html", array());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interface.Address_Book.php	Wed Oct 26 21:44:35 2011 +0200
@@ -0,0 +1,8 @@
+<?
+interface Address_Book {
+	function add_entry($entry);
+	function search_entries($pattern);
+	function delete_entries($ids);
+	function get_all_entries();
+}
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test.php	Wed Oct 26 21:44:35 2011 +0200
@@ -0,0 +1,10 @@
+<?
+$dbh = new PDO("mysql:host=localhost;dbname=abook", "hans", "x", 
+	array(
+		PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+	));
+
+	$dbh->exec("CREATE TABLE IF NOT EXISTS data
+		(name TEXT, tel TEXT, email TEXT)");
+
+?>