MySql query string to sql object - zend-framework2

Using Zend Framework 2 is possible to get a sql string from a tablegateway object, like this:
public function test(){
$sql = $this->tableGateway->getSql();
$select = $sql->select();
$select->where(array('title' => 'abracadabra'));
$select->where
->NEST->
equalTo('id', 1)
->OR->
equalTo('artist', 'Tony')
->UNNEST;
$select->limit(1);
return $this->tableGateway->selectWith($select);
}
//code ignored here//
echo $sql->getSqlstringForSqlObject($select);
I was wondering if it could be possible to do the opposite, and basically set a query string and then get back a tableGateway object, the reason for this is that sometimes is needed to set a where clause dynamically, without having to know where to place/append it, example:
On a single query:
$sql = "select * from tbl_test";
if($isDynamic)
$sql .= ' where test_id=1';
But on more complex query:
$sql = "select * from tbl_test inner join (select * from tbl_test 1) x on 1=1 where test_id is not null group by test_id";
//OF COURSE IT WILL FAIL.
if($isDynamic)
$sql .= ' where test_id=1';
Using zf2 I could potentially do something like
Setting the query string to a sql object.
Then simply do $obj->where(array('test_id'=>1));

To solve this problem I overloaded method Zend\Db\Sql\Select.
For your example of a complex query, I proceed as follows:
Your query : select * from tbl_test inner join (select * from tbl_test 1) x on 1=1 where test_id is not null group by test_id
My query : SELECT * FROM (select * from tbl_test inner join (select * from tbl_test 1) x on 1=1 where test_id is not null group by test_id) tmp WHERE test_id=1;
If your complex query use alias tmp then change in the method renderTable().
Here is how my class is used (change the namespace as need):
use SbmPdf\Model\Db\Sql\Select;
$sql = "select * from tbl_test inner join (select * from tbl_test 1) x on 1=1 where test_id is not null group by test_id";
$select = new Select($sql);
$select->where(array('id' => 1));
Here is my class (change the namespace as need):
/**
* Surcharge de la classe Zend\Db\Sql\Select pour exécuter une requête complexe basée sur une chaine SQL
*
* On a ajouté la méthode setRecordSource qui permet de passer une chaine SQL complète comme source de donnée.
*
* Lorsque la chaine SQL recordSource est donnée (constructeur ou setter), elle remplace la table indiquée dans FROM.
* En définitive, la méthode from() sera ignorée si la méthode recordSource() est appelée.
* Par contre, si on n'appelle pas cette nouvelle méthode, la classe aura un comportement normal (à condition de ne
* rien passer au constructeur).
*
* Ensuite, pour exécuter la requête, il faut pratiquer de la façon suivante :
* $sqlString = $select->getSqlString($dbAdapter->getPlatform());
* $rowset = $dbAdapter->query($sqlString, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
*
* #project sbm
* #package SbmPdf/Model/Db/Sql
* #filesource Select.php
* #encodage UTF-8
* #author DAFAP Informatique - Alain Pomirol (dafap#free.fr)
* #date 19 août 2015
* #version 2015-1
*/
namespace SbmPdf\Model\Db\Sql;
use Zend\Db\Adapter\Driver\DriverInterface;
use Zend\Db\Adapter\ParameterContainer;
use Zend\Db\Adapter\Platform\PlatformInterface;
use Zend\Db\Sql\Select as ZendSelect;
class Select extends ZendSelect
{
private $recordSource;
/**
* On passe le recordSource (sql string) par le constructeur. On ne peut plus passer la table.
*
* #param string $recordSource
*/
public function __construct($recordSource = null)
{
parent::__construct();
$this->recordSource = $recordSource;
}
/**
* On peut aussi le passer par le setter
*
* #param string $recordSource
* #return \SbmPdf\Model\Db\Sql\Select
*/
public function setRecordSource($recordSource)
{
$this->recordSource = $recordSource;
return $this;
}
/**
* Surcharge de la méthode
*
* (non-PHPdoc)
*
* #see \Zend\Db\Sql\Select::processSelect()
*/
protected function processSelect(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
{
$expr = 1;
if (empty($this->recordSource)) {
list ($table, $fromTable) = parent::resolveTable($this->table, $platform, $driver, $parameterContainer);
} else {
list ($table, $fromTable) = $this->resolveTable($this->recordSource, $platform);
}
// process table columns
$columns = array();
foreach ($this->columns as $columnIndexOrAs => $column) {
if ($column === self::SQL_STAR) {
$columns[] = array(
$fromTable . self::SQL_STAR
);
continue;
}
$columnName = $this->resolveColumnValue(array(
'column' => $column,
'fromTable' => $fromTable,
'isIdentifier' => true
), $platform, $driver, $parameterContainer, (is_string($columnIndexOrAs) ? $columnIndexOrAs : 'column'));
// process As portion
if (is_string($columnIndexOrAs)) {
$columnAs = $platform->quoteIdentifier($columnIndexOrAs);
} elseif (stripos($columnName, ' as ') === false) {
$columnAs = (is_string($column)) ? $platform->quoteIdentifier($column) : 'Expression' . $expr ++;
}
$columns[] = (isset($columnAs)) ? array(
$columnName,
$columnAs
) : array(
$columnName
);
}
// process join columns
foreach ($this->joins as $join) {
$joinName = (is_array($join['name'])) ? key($join['name']) : $join['name'];
$joinName = parent::resolveTable($joinName, $platform, $driver, $parameterContainer);
foreach ($join['columns'] as $jKey => $jColumn) {
$jColumns = array();
$jFromTable = is_scalar($jColumn) ? $joinName . $platform->getIdentifierSeparator() : '';
$jColumns[] = $this->resolveColumnValue(array(
'column' => $jColumn,
'fromTable' => $jFromTable,
'isIdentifier' => true
), $platform, $driver, $parameterContainer, (is_string($jKey) ? $jKey : 'column'));
if (is_string($jKey)) {
$jColumns[] = $platform->quoteIdentifier($jKey);
} elseif ($jColumn !== self::SQL_STAR) {
$jColumns[] = $platform->quoteIdentifier($jColumn);
}
$columns[] = $jColumns;
}
}
if ($this->quantifier) {
$quantifier = ($this->quantifier instanceof ExpressionInterface) ? $this->processExpression($this->quantifier, $platform, $driver, $parameterContainer, 'quantifier') : $this->quantifier;
}
if (! isset($table)) {
return array(
$columns
);
} elseif (isset($quantifier)) {
return array(
$quantifier,
$columns,
$table
);
} else {
return array(
$columns,
$table
);
}
}
protected function resolveTable($table, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
{
$alias = null;
if (is_array($table)) {
$alias = key($table);
$table = current($table);
} else {
$alias = 'tmp';
}
$fromTable = $platform->quoteIdentifier($alias);
$table = $this->renderTable($table, $fromTable, false);
if ($alias) {} else {
$fromTable = $table;
}
if ($this->prefixColumnsWithTable && $fromTable) {
$fromTable .= $platform->getIdentifierSeparator();
} else {
$fromTable = '';
}
return array(
$table,
$fromTable
);
}
protected function renderTable($table, $alias = null, $parent = true)
{
if ($parent) {
return parent::renderTable($table, $alias);
} else {
if (empty($alias)) {
$alias = 'tmp';
}
return "($table) AS $alias";
}
}
}

You can use directly where clause with your cording.
public function test(){
$sql = $this->tableGateway->getSql();
$select = $sql->select();
$select->where(array('title' => 'abracadabra'));
$select->where
->NEST->
equalTo('id', 1)
->OR->
equalTo('artist', 'Tony')
->UNNEST;
if($isDynamic){
$select->where(array('test_id' => '1'));
}
$select->limit(1);
return $this->tableGateway->selectWith($select);
}
You can use SQL like this

Related

Reset password symfony 4

I'm trying to create a reset password for users in symfony 4, I have this error
No route found for "GET /change-password": Method Not Allowed (Allow:
POST)
I'm looking for help please
my Controller:
class ChangepasswordController extends Controller
{
private $oldpassword;
private $newpassword;
/**
* #Route("/change-password", name="change_password", defaults={"email=null"})
* #Method("POST")
* #param Request $request
* #param AuthenticationUtils $authenticationUtils
* #param UserPasswordEncoderInterface $passwordEncoder
* #param $email
* #return Response
*/
public function ChangepasswordAction(Request $request, UserPasswordEncoderInterface $passwordEncoder, $email)
{
$user = new User();
$form = $this->createForm(ChangepasswordType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$user = $this->getDoctrine()->getRepository(User::class)->find($email);
} catch (ExceptionInterface $e) {
$this->addFlash('danger', "Cet email n'existe pas.");
}
//Recuperer le nouveau mot de passe tapé par l'utilisateur
$newpassword = $passwordEncoder->encodePassword($user, $user->getPassword());
//recuperer l'ancien mot de passe dans la base de donnéees
$oldpassword = $user->getPassword();
if ($newpassword = $oldpassword) {
$this->addFlash('danger', "Ce mot de passe est dejà utilisé.");
} else {
$user->setPassword($newpassword);
}
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$this->addFlash('success', 'votre mot de passe est bien réinitialisé');
# Redirection sur la page de connexion
return $this->redirectToRoute('connexion');
}
return $this->render(
'security/changemotdepasse.html.twig',
array('form' => $form->createView())
);
}
}
You have to change #Method("POST") to #Method({"GET","POST"}), because your Action is for displaying and processing the form.
I think GET method is not good way to reset password, you can add GET in Methode annotation to fix it but it’s bad way .
The good way is just send data by POST Method and handle it in $request
#Route("/change-password", name="change_password"
Take care of your definition ... - !== _

Convert SQL command to MVC or lambda code

I want this query in lambda expression:
Insert into Tbl_Bill (EmpID, TotalBill, BillByEmployee, BillBySBI, CreatedDate, UpdatedDate, OrderIDs)
select
EmpID, Sum(TotalBill), Sum(TotalBill), Sum(TotalBill),
MIN(CreatedDate), MIN(CreatedDate), COUNT(OrderID)
from
Tbl_Order
group by
EmpID;
Use LinqPad, its a superb tool to queries to linq queries
var queryTbl_Bill =
from Tbl_Order in db.Tbl_Order
group Tbl_Order by new
{
Tbl_Order.EmpID
} into g
select new
{
g.Key.EmpID,
Column1 = g.Sum(p => p.TotalBill),
Column2 = g.Sum(p => p.TotalBill),
Column3 = g.Sum(p => p.TotalBill),
Column4 = g.Min(p => p.CreatedDate),
Column5 = g.Min(p => p.CreatedDate),
Column6 = g.Count(p => p.OrderID != null)
};
foreach (var q in queryTbl_Bill)
{
decimal sbi = 0, emp = 0;
if (q.Column1 < 100.0M)
{
sbi = q.Column1 * 0.75M;
emp = q.Column1 * 0.25M;
}
else if (q.Column1 > 100.0M)
{
sbi = 75.0M;
decimal temp = q.Column1 - 100.0M;
emp = temp + 25.0M;
}
Tbl_Bill iTbl_Bill = new Tbl_Bill
{
EmpID = q.EmpID,
TotalBill = q.Column1,
BillByEmployee = emp,
BillBySBI = sbi,
CreatedDate = DateTime.Now,
UpdatedDate = DateTime.Now,
OrderIDs = q.Column6.ToString(),
Status=true
};
db.Tbl_Bill.Add(iTbl_Bill);
}
db.SaveChanges();
i got answer using linqer

Zend Framework 2 - Common class

I have this message when I change id in id_art on may table in zend framework 2 (I can add and delete but I can't update):
Exception
Fichier:
C:\wamp\www\zf2\module\Annonces\src\Annonces\Model\AnnoncesTable.php:29
Message:
Could not find row 0
Pile d'exécution:
#0 C:\wamp\www\zf2\module\Annonces\src\Annonces\Model\AnnoncesTable.php(48): Annonces\Model\AnnoncesTable->getAnnonces(0)
and this is my script moduleTable:
<?php
namespace Annonces\Model;
use Zend\Db\TableGateway\TableGateway;
class AnnoncesTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
//fonction qui permet d'afficher tous la table "Article"
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
//fonction qui permet de recuperer tout les id de la table "Article"
public function getAnnonces($id)
{
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id_art' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
/*fonction qui permet de ajouet ou modiier un objet de type "Annonce" dans la table "Article"
en fonction de l'id*/
public function saveAnnonces(Annonces $annonces)
{
$data = array(
'titre_art' => $annonces->titre_art,
);
$id = (int) $annonces->id;
if ($id == 0) {
$this->tableGateway->insert($data);
} else {
if ($this->getAnnonces($id)) {
$this->tableGateway->update($data, array('id_art' => $id));
} else {
throw new \Exception('Annonce id does not exist');
}
}
}
//fonction qui permet de supprimé un article en fonction de l'id
public function deleteAnnonces($id)
{
$this->tableGateway->delete(array('id_art' => $id));
}
}
?>
///////////////////////////Controller action:
<?php
namespace Annonces\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Annonces\Model\Annonces;
use Annonces\Form\AnnoncesForm;
class AnnoncesController extends AbstractActionController
{
protected $annoncesTable;
public function indexAction()
{
return new ViewModel(array(
'annonces' => $this->getAnnoncesTable()->fetchAll(),
));
}
public function annonceAction()
{
return new ViewModel(array(
'annonces' => $this->getAnnoncesTable()->fetchAll(),
));
}
public function addAction()
{
$form = new AnnoncesForm();
$form->get('submit')->setValue('Add');
//fonction qui permet d'applet la méthode de création et vérification des champs de saisie de formulaire
$request = $this->getRequest();
if ($request->isPost()) {
$annonces = new Annonces();
$form->setInputFilter($annonces->getInputFilter());
$form->setData($request->getPost());
//apré la validation du formaulaire , remplir l'objet de type "Annonce" et applet la méthode "save annonces" pour ajouter ou modifier l'annonce
if ($form->isValid()) {
$annonces->exchangeArray($form->getData());
$this->getAnnoncesTable()->saveAnnonces($annonces);
// Redirect to list of annonces
return $this->redirect()->toRoute('annonces');
}
}
return array('form' => $form);
}
public function editAction()
{
//test si l'id à était saisie pour la rediriction (add/mod)
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('annonces', array(
'action' => 'add'
));
}
//appllé la fonction getAnnoce //
$annonces = $this->getAnnoncesTable()->getAnnonces($id);
$form = new AnnoncesForm();
$form->bind($annonces);
$form->get('submit')->setAttribute('value', 'Edit');
//vérification les valeur de formulaire de la page "edit"
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($annonces->getInputFilter());
$form->setData($request->getPost());
//applé la méthode "save" apré la validation de formulaire
if ($form->isValid()) {
$this->getAnnoncesTable()->saveAnnonces($form->getData());
// Redirect to list of annoncess
return $this->redirect()->toRoute('annonces');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
public function deleteAction()
{
//test si l'id à était saisie pour la rediriction
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('annonces');
}
//supprimé l'article si l'utilisateur confirm l'action "del"
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->getPost('del', 'No');
if ($del == 'Yes') {
$id = (int) $request->getPost('id');
$this->getAnnoncesTable()->deleteAnnonces($id);
}
// Redirect to list of annoncess
return $this->redirect()->toRoute('annonces');
}
return array(
'id' => $id,
'annonces' => $this->getAnnoncesTable()->getAnnonces($id)
);
}
public function getAnnoncesTable()
{
//permet de recupéré les champs de la table "Article"
if (!$this->annoncesTable) {
$sm = $this->getServiceLocator();
$this->annoncesTable = $sm->get('Annonces\Model\AnnoncesTable');
}
return $this->annoncesTable;
}
}
?>

Zend framework $form->isValid($formData) Return invalid and I dont know why

I have a 2-steps-form (Fancy Name), but, when I submit this form, the validation return false all time, I debugged it and I receive all the parameters I want, but for some reason the isValid is false and get some error in the RadioButton element, this is the code:
This is the forms/Users.php
public function signup()
{
$contryModel = new Application_Model_Country();
$countries = $contryModel->getCountries();
foreach ($countries as $array)
{
if(isset($array['id_country'])){
$countryArr[$array['id_country']] = $array['country'];
}
}
array_unshift($countryArr, '-- Select Your Country --');
$name = new Zend_Form_Element_Text('Name');
$name->setLabel('Name')
->setRequired(true)
->addValidator('NotEmpty');
$lastname = new Zend_Form_Element_Text('LastName');
$lastname->setLabel('Last Name')
->setRequired(true)
->addValidator('NotEmpty');
$email = new Zend_Form_Element_Text('Email');
$email->setLabel('Email')
->setRequired(true)
->addValidator('NotEmpty');
$website = new Zend_Form_Element_Text('Website');
$website->setLabel('Website')
->setRequired(true)
->addValidator('NotEmpty');
$country = new Zend_Form_Element_Select('Country');
$country->setLabel('Country')
->setRequired(true)
->addValidator('NotEmpty')
->addMultiOptions($countryArr);
$city = new Zend_Form_Element_Select('City');
$city->setLabel('City')
->setRequired(true)
->addValidator('NotEmpty')
->addMultiOptions(array('-- Select Your City --'))
->setRegisterInArrayValidator(false)
->setAttrib('disabled',true);
$password = new Zend_Form_Element_Password('Password');
$password->setLabel('Password')
->setRequired(true)
->addValidator('NotEmpty');
$rpassword = new Zend_Form_Element_Password('RepeatPassword');
$rpassword->setLabel('Repeat Password')
->setRequired(true)
->addValidator('NotEmpty');
$why = new Zend_Form_Element_Textarea('Why');
$why->setRequired(true)
->addValidator('NotEmpty')
->setAttrib('cols', '50')
->setAttrib('rows', '4');
$job = new Zend_Form_Element_Text('Job');
$job->setLabel("Job")
->setRequired(true)
->addValidator('NotEmpty');
$boxes = new Application_Model_Colors();
$res = $boxes->getColors();
foreach($res as $colors){
$colorArr[$colors['id']]['color'] = $colors['color'];
$colorArr[$colors['id']]['overColor'] = $colors['overColor'];
}
$color = new Zend_Form_Element_Radio('color');
$color->setLabel('Color')
->addMultiOptions($colorArr)
->addValidator('NotEmpty');
$save = new Zend_Form_Element_Submit('Submit');
$save->setLabel('Save');
$this->addElements(array($name, $lastname, $email, $website, $password, $rpassword, $job, $country, $city, $color, $why, $save));
}
*This is a part of the view * where I format the Radios
<?php
foreach($this->form->color->options as $key=>$colors){
echo "<label><input type='radio' value='$key' name='color'><div class='registrationBoxes' style='background-color:#".$colors['color']."' data-color='".$colors['color']."' data-overColor='".$colors['overColor']."' value='".$colors['color']."'></div></label>";
}
?>
And here is the Controller
public function indexAction()
{
$form = new Application_Form_Users();
$form->signup();
$this->view->form = $form;
if($this->getRequest()->isPost())
{
$formData = $this->getRequest()->getPost();
if($form->isValid($formData))
{
$formData = $this->getRequest()->getPost();
$name = $formData['Name'];
$lastName = $formData['LastName'];
$email = $formData['Email'];
$website = $formData['Website'];
$password = $formData['Password'];
$rpassword = $formData['RepeatPassword'];
$job = $formData['Job'];
$country = $formData['Country'];
$city = $formData['City'];
$color = $formData['color'];
$why = $formData['Why'];
$date_create = date('Y-m-d H:i:s');
$position = new Application_Model_Country();
$latLong = $position->getLatLong($city);
if($password == $rpassword){
$data = array( 'name'=>$name,
'last_name'=>$lastName,
'email'=>$email,
'website'=>$website,
'password'=>md5($password),
'date_create'=>$date_create,
'job'=>$job,
'country'=>$country,
'city'=>$city,
'color'=>$color,
'why'=>$why,
'latitude'=>$latLong['latitude'],
'longitude'=>$latLong['longitude']
);
$add = new Application_Model_Users();
$res = $add->insertUser($data);
if($res){
$this->view->message = "Registration Successfuly.";
$this->_redirect("/contact");
}else{
$this->view->errorMessage = "We have a problem with your registration, please try again later.";
}
}else{
$this->view->errorMessage = "Password and confirm password don't match.";
$form->populate($formData);
}
} else {
$this->view->errorMessage = "There is an error on your registration, all fields are requried";
$form->populate($formData);
}
}
}
a die(var_dump()) return this:
array(12) {
["Name"]=>
string(9) "Some name"
["LastName"]=>
string(13) "Some lastName"
["Email"]=>
string(21) "Someemail#hotmail.com"
["Password"]=>
string(5) "Some "
["RepeatPassword"]=>
string(5) "Some "
["Website"]=>
string(12) "Some website"
["Job"]=>
string(8) "Some job"
["Country"]=>
string(1) "7"
["City"]=>
string(3) "434"
["color"]=>
string(1) "3"
["Why"]=>
string(10) "Emotional!"
["Submit"]=>
string(4) "Save"
}
As you can see, all the parameters are coming and with value, but for no reason the isValid is returning false, some idea guys?
Thanks.-
EDIT
This is a part of the Zend/form.php code required by Tonunu
public function __construct ($options = null)
{
if (is_array($options)) {
$this->setOptions($options);
} elseif ($options instanceof Zend_Config) {
$this->setConfig($options);
}
// Extensions...
$this->init();
$this->loadDefaultDecorators();
}
public function __clone ()
{
$elements = array();
foreach ($this->getElements() as $name => $element) {
$elements[] = clone $element;
}
$this->setElements($elements);
$subForms = array();
foreach ($this->getSubForms() as $name => $subForm) {
$subForms[$name] = clone $subForm;
}
$this->setSubForms($subForms);
$displayGroups = array();
foreach ($this->_displayGroups as $group) {
$clone = clone $group;
$elements = array();
foreach ($clone->getElements() as $name => $e) {
$elements[] = $this->getElement($name);
}
$clone->setElements($elements);
$displayGroups[] = $clone;
}
$this->setDisplayGroups($displayGroups);
}
public function setOptions (array $options)
{
if (isset($options['prefixPath'])) {
$this->addPrefixPaths($options['prefixPath']);
unset($options['prefixPath']);
}
if (isset($options['elementPrefixPath'])) {
$this->addElementPrefixPaths($options['elementPrefixPath']);
unset($options['elementPrefixPath']);
}
if (isset($options['displayGroupPrefixPath'])) {
$this->addDisplayGroupPrefixPaths(
$options['displayGroupPrefixPath']);
unset($options['displayGroupPrefixPath']);
}
if (isset($options['elementDecorators'])) {
$this->_elementDecorators = $options['elementDecorators'];
unset($options['elementDecorators']);
}
if (isset($options['elements'])) {
$this->setElements($options['elements']);
unset($options['elements']);
}
if (isset($options['defaultDisplayGroupClass'])) {
$this->setDefaultDisplayGroupClass(
$options['defaultDisplayGroupClass']);
unset($options['defaultDisplayGroupClass']);
}
if (isset($options['displayGroupDecorators'])) {
$displayGroupDecorators = $options['displayGroupDecorators'];
unset($options['displayGroupDecorators']);
}
if (isset($options['elementsBelongTo'])) {
$elementsBelongTo = $options['elementsBelongTo'];
unset($options['elementsBelongTo']);
}
if (isset($options['attribs'])) {
$this->addAttribs($options['attribs']);
unset($options['attribs']);
}
$forbidden = array('Options', 'Config', 'PluginLoader', 'SubForms',
'View', 'Translator', 'Attrib', 'Default');
foreach ($options as $key => $value) {
$normalized = ucfirst($key);
if (in_array($normalized, $forbidden)) {
continue;
}
$method = 'set' . $normalized;
if (method_exists($this, $method)) {
$this->$method($value);
} else {
$this->setAttrib($key, $value);
}
}
if (isset($displayGroupDecorators)) {
$this->setDisplayGroupDecorators($displayGroupDecorators);
}
if (isset($elementsBelongTo)) {
$this->setElementsBelongTo($elementsBelongTo);
}
return $this;
}
In order to check if your form is valid, you have to put your data into it, using this method !
$form->setData($formData)
and then you can ask for validation
$form->isValid()
So what you need is :
$formData = $this->getRequest()->getPost();
$form->setData($formData);
if($form->isValid()){
//Blablablabla
}

How to handle the meta description/keywords in a Zend Framework 2 application?

The default page title defined in the layout file can be extended (PREPEND/APPEND) or replaced (SET) with a title specific for the current view.
Such behavior I've also been expecting for the HeadMeta view helper. Now I cannot find any proper way to "extend" the default descrition/keywords, that I defined in the layout file.
Instead of it I can add a further meta tag with append(...)/appendName(...) (similary to adding style or script file with HeadLink or HeadScript). But it doesn't make sense for descrition and keywords meta tags.
Is there a recommended approach to handle this? How to handle the description/keywords meta tags?
Here is a quick&dirty workaroud, I'm currently using (for a clean solution instead of an ugly workaround changes at the framework are needed):
HeadMeta view helper
<?php
namespace MyNamespace\View\Helper;
use stdClass;
use Zend\View;
use Zend\View\Exception;
use Zend\View\Helper\HeadMeta as ZendHeadMeta;
use Zend\View\Helper\Placeholder\Container\AbstractContainer;
class HeadMeta extends ZendHeadMeta {
const DELIMITER = ' - ';
/**
* #see \Zend\View\Helper\HeadMeta::__invoke()
*/
public function __invoke($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = AbstractContainer::APPEND) {
parent::__invoke($content, $keyValue, $keyType, $modifiers, $placement);
return $this;
}
/**
* #see \Zend\View\Helper\HeadMeta::append()
*/
public function append($value) {
if ($value->name == 'description') {
$this->updateDescription($value, AbstractContainer::APPEND);
} else if ($value->name == 'keywords') {
$this->updateKeywords($value, AbstractContainer::APPEND);
} else {
parent::append($value);
}
}
/**
* #see \Zend\View\Helper\HeadMeta::prepend()
*/
public function prepend($value) {
if ($value->name == 'description') {
$this->updateDescription($value, AbstractContainer::PREPEND);
} else if ($value->name == 'keywords') {
$this->updateKeywords($value, AbstractContainer::PREPEND);
} else {
parent::prepend($value);
}
}
// Not working correctly!
// Can cause a
// Fatal error: Maximum function nesting level of '100' reached, aborting!
/**
* #see \Zend\View\Helper\HeadMeta::set()
*/
public function set($value) {
if ($value->name == 'description') {
$this->updateDescription($value, AbstractContainer::SET);
} else if ($value->name == 'keywords') {
$this->updateKeywords($value, AbstractContainer::SET);
} else {
parent::set($value);
}
}
/**
* If a description meta already exsists, extends it with $value->content,
* else creates a new desctiprion meta.
* #param \stdClass $value
* #param string $position
*/
public function updateDescription(\stdClass $value, $position = AbstractContainer::SET) {
$descriptionExists = false;
foreach ($this->getContainer() as $item) {
if ($this->isDescription($item)) {
switch ($position) {
case AbstractContainer::APPEND:
$descriptionString = implode(static::DELIMITER, array($item->content, $value->content));
break;
case AbstractContainer::PREPEND:
$descriptionString = implode(static::DELIMITER, array($value->content, $item->content));
break;
case AbstractContainer::SET:
default:
$descriptionString = $value->content;
break;
}
$item->content = $descriptionString;
$descriptionExists = true;
}
}
if (!$descriptionExists) {
switch ($position) {
case AbstractContainer::APPEND:
parent::append($value);
break;
case AbstractContainer::PREPEND:
parent::prepend($value);
break;
case AbstractContainer::SET:
default:
parent::set($value);
break;
}
}
}
/**
* If a keywords meta already exsists, extends it with $value->content,
* else creates a new keywords meta.
* #param \stdClass $value
* #param string $position
*/
public function updateKeywords(\stdClass $value, $position = AbstractContainer::SET) {
$keywordsExists = false;
foreach ($this->getContainer() as $item) {
if ($this->isKeywords($item)) {
switch ($position) {
case AbstractContainer::APPEND:
$keywordsString = implode(', ', array($item->content, $value->content));
break;
case AbstractContainer::PREPEND:
$keywordsString = implode(', ', array($value->content, $item->content));
break;
case AbstractContainer::SET:
default:
$keywordsString = $value->content;
break;
}
$item->content = $keywordsString;
$keywordsExists = true;
}
}
if (!$keywordsExists) {
parent::append($value);
}
}
/**
* #return description meta text
*/
public function getDescription() {
$description = null;
foreach ($this->getContainer() as $item) {
if ($this->isKeywords($item)) {
$description = $item->content;
break;
}
}
return $description;
}
/**
* #return keywords meta text
*/
public function getKeywords() {
$keywords = null;
foreach ($this->getContainer() as $item) {
if ($this->isKeywords($item)) {
$keywords = $item->content;
break;
}
}
return $keywords;
}
/**
* Checks, whether the input $item is an approproate object for $this->container
* and wheter it's a description object (its name is "description")
* #param stdClass $item
* #throws Exception\InvalidArgumentException
* #return boolean
*/
public function isDescription(stdClass $item) {
if (!in_array($item->type, $this->typeKeys)) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid type "%s" provided for meta',
$item->type
));
}
return $item->name == 'description';
}
/**
* Checks, whether the input $item is an approproate object for $this->container
* and wheter it's a keywords object (its name is "keywords")
* #param stdClass $item
* #throws Exception\InvalidArgumentException
* #return boolean
*/
public function isKeywords(stdClass $item) {
if (!in_array($item->type, $this->typeKeys)) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid type "%s" provided for meta',
$item->type
));
}
return $item->name == 'keywords';
}
}
/module/Application/view/layout/layout.phtml
<?php
$this->headMeta()->appendName(
'description',
$this->translate('default description')
);
$this->headMeta()->appendName(
'keywords',
implode(', ', array(
$this->translate('default keyword 1'),
$this->translate('default keyword 2'),
$this->translate('default keyword 3'),
))
);
echo $this->headMeta();
?>
view script
<?php
$this->headMeta()->setName('keywords', implode(
', ',
array(
$this->translate('view specific keyword 1'),
$this->translate('view specific keyword 2'),
$this->translate('view specific keyword 3'),
)
));
$this->headMeta()->setName('description', 'view specific description');
?>
Linking to my answer here: How to change meta tags in zend framework layout
Here's what worked for me. In the layout file you have to make sure that the meta tags are echoed. It's empty at the stage but you will be marking where the meta tags will be outputted. This only disadvantage with this method would be that there doesn't seem to be a way to have a default meta tag so you will have to add the meta tag in each view file.
In the layout file
<?php echo $this->headMeta(); ?>
In the view .phtml file
$this->headMeta("test description text", "description");

Resources