Zend_Acl / Zend_Auth / Zend_Navigation

Today i was looking for a nice tutorial about how to use Zend_Acl to check on every page request if the user has the right to access the controller/action. Now, there are some infos about that out there, but either they’re outdated, or not useable, cause the code is incomplete, or doesnt work at all.
So this is the solution i came up with during the day. I will start at the entry point, the Bootstrap.php.

  1. protected function _initAuth() {
    $this->bootstrap(‘frontController’);
    // set up the roles and resources
    $acl = H_Plugin_Acl::getInstance();
    $fc = $this->getResource(‘frontController’);
    // check the rights vs. the roles
    $fc->registerPlugin(new H_Plugin_Accescontrol($acl), 10);
    }
  2. Now, my acl class:
    class H_Plugin_Acl extends Zend_Acl
    {
    const ROLE_GUEST = ‘guest’;
    const ROLE_ADMIN = ‘admin’;
    protected static $_instance;
    / Singleton pattern /
    protected function __construct()
    {
    $this->addRole(new Zend_Acl_Role(self::ROLE_GUEST));
    $this->addRole(new Zend_Acl_Role(self::ROLE_ADMIN), self::ROLE_GUEST);
    $this->addResource(new Zend_Acl_Resource(‘index’))
    ->addResource(new Zend_Acl_Resource(‘admin’))
    ->addResource(new Zend_Acl_Resource(‘auth’))
    ;
    $this->allow(‘guest’, ‘index’);
    $this->allow(‘guest’, ‘auth’);
    $this->allow(‘admin’, ‘admin’);
    return $this;
    }
    public static function getInstance()
    {
    if (null === self::$_instance) {
    self::$_instance = new self();
    }
    return self::$_instance;
    }
    }
  3. Now, the class to check the user against the acl:
    class H_Plugin_Accescontrol extends Zend_Controller_Plugin_Abstract {
    private $auth;
    private $acl;
    public function __construct(Zend_Acl $acl){
    $this->auth = Zend_Auth::getInstance();
    $this->acl = $acl;
    }
    public function preDispatch(Zend_Controller_Request_Abstract $request) {
    if ($this->auth->hasIdentity()){// && Zend_Registry::isRegistered(‘strRole’)){
    // fetchbyloginname calls a ModelMapper, and the method retrieves the user from db which is logged in
    // also have a look at: https://github.com/sveri/ZFP where we have set up a nice caching system for zend
    $objBenutzer = Model_BenutzerMapper::getCachedInstance()->fetchByLoginname($this->auth->getIdentity());
    $role = $objBenutzer->getRole();
    Zend_Registry::set(‘numBenutzerId’, $objBenutzer->getId());
    Zend_Registry::set(‘strRole’, $objBenutzer->getRole());
    } else {
    $role = ‘guest’;
    }
    $resource = $request->getControllerName();
    if (!$this->acl->has($resource)) {
    $resource = null;
    }
    if (!$this->acl->isAllowed($role, $resource)) {
    if ($this->auth->hasIdentity()) {
    // angemeldet, aber keine Rechte -> Fehler!
    $request->setModuleName(‘default’);
    $request->setControllerName(‘error’);
    $request->setActionName(‘forbidden’);
    } else {
    //nicht angemeldet -> Login
    $request->setModuleName(‘default’);
    $request->setControllerName(‘index’);
    $request->setActionName(‘index’);
    }
    }
    }
    }
  4. And finally the navigation with acl, which is very simple, this is what i have in my standard layout.phtml:
    $HPN = new H_Plugin_Navigation();
    $nav = $HPN->getNav();
    $acl = H_Plugin_Acl::getInstance();
    $strRole = null;
    if(Zend_Registry::isRegistered(‘strRole’)){
    $strRole = Zend_Registry::get(‘strRole’);
    }
    echo $this->navigation($nav)->menu()->setAcl($acl)->setRole($strRole);

Thats basically it, my user table consists of at least 3 entries: role, loginname, passwort, where role is an enum of all the available roles in the Zend_Acl.
This is a very basic example, of course you can get that all cached, read the roles und rules from db, etc. but for small projects, thats most of the times to much overhaul :-)

Ah, and not to forget, i wont paste the Zend_Auth class here, cause thats pretty standard, something that can be found everywhere :-)

Zend_Db_Table_Abstract – createRow new dbtable Column vanished?

For everybody using the function createRow() from Zend_Db_Table_Abstract and wondering why new columns in any db – table dont arise in the returned row. He shall be advised to read the phpdoc of createRow where it says:
Fetches a new blank row (not from the database).
Yep, thats important, as it reads from the metadatacache, and you have to delete it everytime you add a new column to a certain table.

This took me 30 minutes to figure it out :-D

Zend Caching – Which backend to use?

At my current business we are developing a nice web application for a limited user base, based on the Zend engine (only partial), and right around christmas time we met the question of how to cache and what to cache.

What to cache was fast resolved, we decided to cache our models, and the object entities they return. For that we do use the Pet model library, a small, but very effective, caching library: https://github.com/cyberpet/ZFP.

Then, the next question was how, so, what follows is a short write up of what we came to, and the possibilities we still have:

Current State

We right now use the Zend_Cache_Backend_Twolevels with APC as its fast backend and sqlite as its slow backend. The sqlite db sits in a ramdisk to execute the writing into the cache fast enough.

How it came to this decision

Zend offers several caching backends, namely:

  • Xcache
  • Apc
  • Memcached

All three are basd in the RAM –

  • File
  • Sqlite

Whereas these both lie on the filesystem.

Because of their backends, there are two great differences, File access, is, especially while writing into the cache, much slower than memory acces, so, you of cause think, uhm, lets cache into the fast backends, like apc or memcache, but wait, theres more to come.
The fast backends dont support tags, tags are important? You may think? Then, dont take the fast backend.
There was a lot of discussion going on about using tags in the RAM backends, but basically the zend developers came down to avoid them, cause nobody can guaranty when some pages in the RAM get dropped, or not, and then there may be tag data lossed, maybe resulting in wrong data retrieval.

The pet model, relies on tags, so we have to take the slow backends that support tags.
But using them is really a showstopper if you have to cache a lot of entries from time to time, its like 20-30 times slower.

Two Levels for the rescue
But wait, there is a solution already there, called Zend_Cache_Backend_Two_Levels, at least it seems like that, Two levels reads and writes from two backends, one slow, and fast the other one. It stores both the tags and the cached data to the slow backend, and then only the cached data to the fast backend.

But, the problem remains, using sqlite as slow backend means, you still have file access for the slow backend, which, especially for many thousand cached objects means, poooooor performance.

And this is where the ram disk comes into the game, mount a ramfs partition and store the sqlite DB there, the db will handle eventual data losses for you and report errors, but you still have a fast slow backend.

Cache data in slow backend? Not only tags?
I also measured if there is a performance gain when only storing the tags in the sqlite DB and not the tags + cached data, on my system i came down to 17%, what didnt seem enough for us, to change a proved caching mechanism from zend to something untested. But maybe later, when 17% seem to be system critical, we even may come and catch the last remaining percent too.

File backend?
Then why not using the file backend in the ram disk? Cause if you have a lot of small files you still have the time consuming fopen, fwrite, fclose for every file, which takes the performance down, compared to sqlite.

Mysql memory table?
I even tried that one as store for the tags, but it also performs very slow, even slower then the file backend in the ram disk.

Slow/Fast? Read/Write?
Everything i said above about the performance was meant for writing into the cache, as that seems to be our greatest problem right now.

Regarding the reads from the backends they all come down to the same as long as you use a Two Level or a slow backend, page generation for our test page takes from 2 to 3.5 seconds, depending on the chosen backend.

Pure fast – RAM backends are still faster, i came down to like 1 second reading for the test page, so there may be options to get more performance, but right now we dont depend on the last second.

Testcase
Our testcase was an overview page which lists all our suppliers with a lot of information, spread over 10 tables in the database.

Views? Database anyone?
There still are some queries left, which cannot be cached, due to dependency hell under the mappers (the only big disadvantage right now of the pet model :-(), they will basically brought down, with their logic, into the database, and then the results will lie there as a view, waiting to deliver its last data, until the and of days.

Conclusion
A mix of Caching, database views, and the use of all the ram our server can give us boils down to a developer friendly (use of application layer logic for development) environment with an acceptable performance at least.
The last thing that comes to my mind is that Cache is like Security, its not a state, its a process, and who knows where it takes us next :-)

Script to draw a border around an active window with autohotkey

Today i wrote a little script that draws borders around certain windows in Windows ;-)
This is especially useful if you play poker, or something similar, and need attention on certain windows.
The script uses the autohotkey framework, which you can find under: http://www.autohotkey.com/

Copy the code in a file called foobar.ahk and start it. Inside itself you find two variables:
border_thickness which sets the thickness of the borders and
Table_String which looks for the name of the window around which it should draw the border.

The script looks only for active windows, but you can easily add functionality to it, just look at the autohotkey homepage.

So here it comes:

#Persistent

SetTimer, DrawRect, 50
border_thickness = 5
Table_String = Table

DrawRect:
;Loop {
; WinGetClass, class, A
;if (class = “#32770″)
WinGetTitle, title, A
IfInString, title, %Table_String%
{
WinGetPos, x, y, w, h, A
Gui, +Lastfound +AlwaysOnTop +Toolwindow
iw:= w+4
ih:= h + 4
w:=w+ 8
h:=h + 8
x:= x -border_thickness
y:= y -border_thickness
Gui, Color, FF0000
Gui, -Caption
WinSet, Region, 0-0 %w%-0 %w%-%h% 0-%h% 0-0 %border_thickness%-%border_thickness% %iw%-%border_thickness% %iw%-%ih% %border_thickness%-%ih% %border_thickness%-%border_thickness%
Gui, Show, w%w% h%h% x%x% y%y% NoActivate, Table awaiting Action
}
;}
return

76 Jahre nach der letzten Bücherverbrennung geht ein Geist um in Deutschland

Ein Geist beschwört durch abartiges Ausnutzen von Emotional schwerst verletzten Menschen.
Das Aktionsbündnis Amoklauf Winnenden ruft für den 17. Oktober 2009 dazu auf Killerspiele, also Spiele die das Töten von Menschen simulieren, in einen Container zu werfen und sie damit aus der Hand zu geben. Wen das an die Bücherverbrennung der Nazis erinnert, der erinnert sich zu Recht. Niemandem steht es zu verletzte Menschen deren Kinder getötet wurden für so eine Aktion zu instrumentalisieren. Das ist menschenverachtend und nützt weder den Familien noch den Opfern. Geholfen ist damit gar niemandem. Und auch wenn der Spruch saudämlich ist, aber Killerspiele töten keine Menschen, Menschen töten keine Menschen.
Dasselbe gilt für Pistolen, Gewehre, Messer und Atombomben. Letztendlich töten immer Menschen Menschen. Und die Schuld daran einem Computerspiel zu geben ist nicht nur populistisch sondern lenkt im gefährlichen Maße von den wahren Gründen ab.
Welche das sind, das mag ich nicht beurteilen, mir fehlt dazu sowohl die Kompetenz als auch das Hintergrundwissen. Aber dass die Spiele daran unschuldig sind ist offensichtlich und das ist es nicht erst seit heute.
Und jeder der bei einer solchen Aktion mitmacht gehört zumindest auf die Analogie zur Bücherverbrennung hingewiesen.

Hier noch der Link über den ich darauf gestoßen bin:
http://www.pcaction.de/Aktionsbuendnis-Amoklauf-Winnenden-will-Killerspiele-vernichten/News/article/view/2900/

Ha ha ha, Killerspiele auf Rezept?

Bald ist es so weit.
Wenn man sich die Überlegungen hernimmt Killerspiele bald
ganz verbieten zu wollen und da die neuesten Forschungsergebnisse
dass Killerspiele langanhaltend die Sehfähigkeit verbessern (insbesondere die
Kontrastempfindlichkeit der Augen) dann könnte man zu der
logischen Schlussfolgerung kommen dass Killen an der Konsole bald
von den Augenärzten verschrieben wird.

Bekommt man dann die Spiele in der Apotheke?
Muss man da auch nur 5.x € zuzahlen?
Das wär doch mal was, immer die neuesten Spiele
zu Hause, gesponsort von der Krankenkasse :-D

Quelle (heise.de):
Forscher-Actionspiele-verbessern-das-Sehvermoegen

Endlich

mal wieder ein wahrer Artikel ueber
das mittlerweile fast komplett richtig
heruntergekommen Fernsehen:
Fernsehen und die Gebuehren

Am besten find ich den Satz hier:
“Dabei ist der Niedergang des Mediums Fernsehen schlichtweg atemberaubend. Kaum stellt man fest, dass mit einer Sendung wie “Big Brother” endgültig der Boden erreicht sein müsste, ist man gezwungen zu erfahren, dass es mit der nächsten Casting-Show immer noch ein gutes Stück darunter geht.”