I am using Zend 2.0 and I have never used EXTJS in combination with Zend.
Here is my extjs code in view/login/index.phtml:
<?php $this->inlineScript()->captureStart() ?>
var LoginWindow
Ext.onReady(function() {
LoginWindow = new Ext.create('Ext.window.Window',{
title: 'Login',
closable: false,
draggable: false,
resizable: false,
width: 370,
items: [
Ext.create('Ext.form.Panel', {
id: 'LoginForm',
bodyPadding: 5,
width: 350,
url: '/',
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'Username',
name: 'user',
allowBlank: false
},{
fieldLabel: 'Password',
inputType: 'password',
name: 'pw',
allowBlank: false
}],
// Reset and Submit buttons
buttons: [{
text: 'Reset',
handler: function() {
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true,
disabled: true,
handler: function() {
var form = this.up('form').getForm();
}
}]
})
]
});
Ext.getBody().mask()
LoginWindow.show()
});
<?php $this->inlineScript()->captureEnd() ?>
Now I am not sure how to send the username/password to LoginController.php and use the model to authenticate username/password from the database table.
Any example or possible solution would really help.
Please do not consider the following as a ready to use solution. I also added some more parts that you will find useful when you start managing your logins. The main part for you should be the routing an the controller. I also spared the view content, except the ExtJS part of it. Anyway, I hope this helps you.
First there where some issues within your form. Try the following one
var loginWindow;
Ext.onReady(function() {
loginWindow = new Ext.create('Ext.window.Window',{
title: 'Login',
closable: false,
draggable: false,
resizable: false,
width: 370,
modal: true,
items: [
Ext.create('Ext.form.Panel', {
id: 'LoginForm',
bodyPadding: 5,
width: 350,
layout: 'anchor',
defaults: {
anchor: '100%'
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Username',
name: 'user',
allowBlank: false
},{
fieldLabel: 'Password',
inputType: 'password',
name: 'pw',
allowBlank: false
}],
url: 'Login/Auth', // first one should be your controller, second one the controller action (this one need to accept post)
buttons: [
{
text: 'Reset',
handler: function() {
this.up('form').getForm().reset();
}
},
{
text: 'Submit',
formBind: true,
disabled: true,
handler: function() {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', 'Authenticated!');
},
failure: function(form, action) {
Ext.Msg.alert('Failed', 'Authentication Failed');
}
});
}
}
}
]
})
]
}).show();
// Ext.getBody().mask(); <- modal property does the same
});
Now to ZF2
The Routing
Each page of the application is known as an action and actions are grouped into controllers within modules. Hence, you would generally group related actions into a controller.
The mapping of a URL to a particular action is done using routes that are defined in the module’s module.config.php file. You should add a route for the Login actions. This is the updated module config file with the new code within commentation blocks.
<?php
return array(
'controllers' => array(
'invokables' => array(
'Login\Controller\Login' => 'Login\Controller\LoginController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'login' => array(
'type' => 'segment',
'options' => array(
'route' => '/login[/:action][/:username][/:password]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'username' => '[a-zA-Z][a-zA-Z0-9_-]*',
'password' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Login\Controller\Login',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'login' => __DIR__ . '/../view',
),
),
);
The name of the route is ‘login’ and has a type of ‘segment’. The segment route allows you to specify placeholders in the URL pattern (route) that will be mapped to named parameters in the matched route. In this case, the route is /login[/:action][/:id] which will match any URL that starts with /login. The next segment will be an optional action name, and then finally the next segment will be mapped to an optional id. The square brackets indicate that a segment is optional. The constraints section allows you to ensure that the characters within a segment are as expected, so you have limited actions to starting with a letter and then subsequent characters only being alphanumeric, underscore or hyphen.
The controller
Now you need to set up the controller. The controller is a class that is generally called {Controller name}Controller. Note that {Controller name} must start with a capital letter. This class lives in a file called {Controller name}Controller.php within the Controller directory for the module. In your case that would be something like module/Login/src/Login/Controller. Each action is a public method within the controller class that is named {action name}Action. In your case {action name} should start with a lower case letter.
<?php
namespace Login\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class LoginController extends AbstractActionController
{
public function authenticateAction($username, $password)
{
$params = array('driver' => 'driver',
'dbname' => 'name');
$db = new DbAdapter($params);
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
// Oversimplified example without even hashing the password
$adapter = new AuthAdapter($db,
'Logins',
'username',
'password'
);
// get select object (by reference)
$this->_adapter->setIdentity($username);
$this->_adapter->setCredential($password);
$result = $adapter->authenticate();
if($result->isValid()) {
// authenticated
}
}
protected $loginTable;
public function getLoginTable()
{
if (!$this->loginTable) {
$sm = $this->getServiceLocator();
$this->loginTable = $sm->get('Login\Model\LoginTable');
}
return $this->loginTable;
}
}
The view script
These files will be executed by the DefaultViewStrategy and will be passed any variables or view models that are returned from the controller action method. These view scripts are stored in our module’s views directory within a directory named after the controller. Create these four empty files now:
module/Login/view/login/login/authenticate.phtml`
The Model
Create a file called Login.php under module/Login/src/Login/Model:
<?php
namespace Login\Model;
class Login
{
public $id;
public $username;
public $password;
public function exchangeArray($data)
{
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->username = (isset($data['username'])) ? $data['username'] : null;
$this->password = (isset($data['password'])) ? $data['password'] : null;
}
}
Create your LoginTable.php file in module/Login/src/Login/Model directory like this:
<?php
namespace Login\Model;
use Zend\Db\TableGateway\TableGateway;
class LoginTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function getLogin($id)
{
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
public function saveLogin(Login $login)
{
$data = array(
'username' => $login->password,
'password' => $login->username,
);
$id = (int)$login->id;
if ($id == 0) {
$this->tableGateway->insert($data);
} else {
if ($this->getLogin($id)) {
$this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Form id does not exist');
}
}
}
public function deleteLogin($id)
{
$this->tableGateway->delete(array('id' => $id));
}
}
Use ServiceManager to configure the table gateway and inject into the LoginTable
Add this method to the bottom of the Module.php file in module/Login.
<?php
namespace Login;
// Add these import statements:
use Login\Model\Login;
use Login\Model\LoginTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
class Module
{
// getAutoloaderConfig() and getConfig() methods here
// Add this method:
public function getServiceConfig()
{
return array(
'factories' => array(
'Login\Model\LoginTable' => function($sm) {
$tableGateway = $sm->get('LoginTableGateway');
$table = new LoginTable($tableGateway);
return $table;
},
'LoginTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Login());
return new TableGateway('login', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
}
Finally, you need to configure the ServiceManager so that it knows how to get a Zend\Db\Adapter\Adapter. Modify config/autoload/global.php with following code
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2tutorial;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
You should put your database credentials in config/autoload/local.php
<?php
return array(
'db' => array(
'username' => 'YOUR USERNAME HERE',
'password' => 'YOUR PASSWORD HERE',
),
);
You may also find the following code snippets useful (take a look at tests and demos):