Abstract Zend Data Mapper Class for Zend Framework

 Development, Zend Framework  Comments Off on Abstract Zend Data Mapper Class for Zend Framework
Aug 232011
 

I have started a new project with a fellow programmer, Peter Fortune @pfortune. The project is a group organising tool, aimed at the Irish market and will be hosted under the domain http://groups.ie.

So when discussing this project, we decided to use Zend Framework as we both are very comfortable with PHP and I have used Zend Framework in the past. After working on the design of the database schema, it came to laying the ground work for the project. Building the models fell under my todo list and so I set to work.

So I spent a little time coming up with what I think is a reasonable Abstract class for the Applications data mapping classes to extend. I know quite a few developers prefer to use doctrine with Zend Framework, and when the project progresses, this may be something we will consider using also, but for the time being, I went with the inbuilt tools Zend_Db_Table_Abstract etc. So here is the class I ended up with. Please give me your thoughts and criticisms and point out any gaping errors.


setDbTable($tableName);
$this->_model = $model;

}

public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (!$dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('you must pass a class that extends Zend_Db_Table_Abstract');
}
$this->_dbTable = $dbTable;
return $this;
}

/**
*
* @return Zend_Db_Table_Abstract
* return concrete child
*/
public function getDbTable()
{
if (null === $this->_dbTable) {
throw new Exception("no dbtable set");
}

return $this->_dbTable;
}

/**
*
* @param Application_Model_RowAbstract $row
* @return array
* returns an array of concrete children extending Application_Model_RowAbstract
*/
public function findAllByExample(Application_Model_RowAbstract $row)
{
//returns all public properties and their values in assoc array
$props = get_object_vars($row);
$sql = $this->getDbTable()->select();
foreach($props as $property=>$value){
if(!NULL == $value)
$sql->where(''.$property.' = ?',$value);
}

$rows = $sql->query()->fetchAll();
$ret = array();
foreach($rows as $row){
$ret[]= new $this->_model($row);
}
return $ret;

}

/**
*
* @param Application_Model_RowAbstract $row
* @return Application_Model_RowAbstract
* returns a concrete child
*/
public function findRowByExample(Application_Model_RowAbstract $row){
$props = get_object_vars($row);
$sql = $this->getDbTable()->select();
foreach($props as $property=>$value){
if(! NULL == $value)
$sql->where(''.$property.' = ?',$value);
}

$sql->limit(1);
$rows = $sql->query()->fetchObject($this->_model);
return $rows;
}

/**
*
* @param Application_Model_RowAbstract $row
*
* chooses to save or update based on whether the primary key is set or not
*/
public function saveUpdate(Application_Model_RowAbstract $row)
{
//get pri key from get_primary() public method added
//to concrete implimentation of Zend_Db_Table_Abstract
$prikey = $this->getDbTable()->get_primary();
$prikey = $prikey[1];
$data = get_object_vars($row);
if(isset($row->$prikey)){
//update
$updateData = array();
foreach($data as $property=>$value){
if(!NULL == $value)
$updateData[$property]=$value;
}
print_r($updateData);
//$this->getDbTable()->update($updateData, ''.$prikey.'='.$row->$prikey.'');
}else{
//insert
$this->getDbTable()->insert($data);
}

}

/**
*
* @param mixed $value
* @return Application_Model_RowAbstract
* the value is the value of the primary key set for the row
*/
public function findWherePriKeyEquals($value){

$row = $this->getDbTable()->find($value);
$ret = $row->current();
return new $this->_model($ret->toArray());

}

}

so that’s it. As you can see you have most functionality there. You can create a dummy object and find all that match its values in the database. You can update and save an objects values
and you can find based on simple rules. All of this means that the concrete sub classes have a lot less work to do. Hope this is helpful.

 

If you have’t heard Mozilla identity labs has introduced a new way to login into sites called browserid. We have all become familiar with the “sign in with twitter” and “connect with Facebook” buttons on sites that enable us to have a centralised login to many of our favourite web services.

These centralised logins are very useful, but are ultimately controlled by a company. So into the breach steps Mozilla offering an openid type login service. Browserid is open source and you can choose to use mozilla as an authentication service or you can set up your own. I’m going to show you how to setup this service as a login and using Mozilla as the authenticator.

So assuming you have a login image with an Id attribute of “login” the following code should work in most modern browsers. I’m using jquery as the javascript framework.



$('document').ready(function (){

$('img.login').click(function(){
navigator.id.getVerifiedEmail(gotVerifiedEmail);
});

});
//this function is called in the above function
function gotVerifiedEmail(assertionObj){
If(assertionObj){
//Ajax to a login controller
$.ajax({
url:"/yourcontroller/youraction",
data:{assertion:assertionObj},
dataType:"json",
type:"post",
success:function(data,textStatus,jqXHR){
// do your thing
},
error:function(){
// something went wrong with ajax call
}
});
}else{
// something went wrong
}
}

So that’s the JavaScript part however we still need to verify the assertion with Mozilla. You can do this with JavaScript too. In the above code you would replace the call to your controller with
The following URL:
“https://browserid.org/verify?assertion=”+window.encodeURIComponent(assertionObj)+”&audience=”+window.encodeURIComponent(window.location.host);

In my controller class I do the following in a grails app:

def browserIdLogin ={

If(params.assertion){
def url = new URL(
"https://browserid.org/verify?assertion=${URLEncoder.encode(params.assertion)}&audience=
${URLEncoder.encode(request.getHeader('HOST'))}");

def jsonResponse= JSON.parse(url.text)

Println jsonResponse
}

}

// this will output something like [audience:localhost:8080, issuer:browserid.org:443, email:[email protected], status:okay, valid-until:1310908947530]

So you now you are dealing with an authentic user with authenic email address. Now you can do as you please. if this user already has an account you can load up their account details and set the session parameters etc or if they have no account you can send them to complete an account creation (if you need more details than the email address). After they complete this they can then sign in without needing to remember a password etc.

In php you could use the CURL library or open a socket etc or you could even just use


email;
?>

Anyway hope this is helpful. There is plenty of info on browserid and they also have example code.

© 2012 Craig Brookes Suffusion theme by Sayontan Sinha