I have this model:
class Application_Model_Categories extends Zend_Db_Table_Abstract
{
protected $_name = 'categories';
protected $_referenceMap = array(
'Stores' => array (
'columns' => 'store_id',
'refTableClass' => 'Application_Model_Races',
'refColumns' => 'id')
);
}
Then in my controller:
$race = new Application_Model_Races();
$find = $this->race->find(1);
$current = $find->current();
$categories = $current->findDependentRowset('Application_Model_Categories');
this is returning all the categories. i need to apply a filter to return only the categories with parentId = 0
I´m new to ZF1 so if you also see that im getting the data incorrectly in the controller please let me know. thank you
Simply,
$race = new Application_Model_Races();
$find = $this->race->find(1);
$current = $find->current();
$select = $race->getAdapter()->select()->where('parentId = 0');
$categories = $current->findDependentRowset(
'Application_Model_Categories',
null,
$select
);
By providing a Zend_Db_Select object as third argument to findDependentRowset table row method call, you can add as much conditions as you want (even adding limit, setting order, ...).
Edit
Well, you should create a custom Row Class, name it Application_Model_Race for example, or Application_Model_RaceRow.
class Application_Model_RaceRow extends Zens_Db_Table_Row_Abstract
{
public function getParentCategories()
{
$select = $this->getTable()->select()->where('parentId = 0');
return $this->findDependentRowset(
'Application_Model_Categories',
null,
$select
);
}
}
Add a _rowClass to your Application_Model_Races class.
class Application_Model_Races extends Zend_Db_Table_Abstract
{
protected $_rowClass = 'Application_Model_RaceRow';
/** Your old code **/
}
Hope it helps
Related
i'm trying to update an object by using this code :
The column co_nbre will be updated to 0 !!!!
I think you will help me to fix this issue and thnx a lot.
public function update($model) {
$data = get_object_vars($model);
$id = (int) $model->id;
$this->tableGateway->update($data, array('id' => $id));
}
and this is how did i use it in my controller:
if ($form->isValid()) {
$data = $form->getData();
$addi_info = new Addiinfo();
$addi_info->exchangeArray($data);
$addi_info->co_nbre = $request->getPost("co_nbre");
$addi_info->user_pin = $this->layout()->pin;
$addi_info->co_latitude = $request->getPost("latitude");
$addi_info->co_longitude = $request->getPost("longitude");
$addi_info->co_adresse = $request->getPost("adresse");
print_r($addi_info);die;
$checkuser=$this->getAddiinfoTable()->getAddiInfoByUserPin($user_pin);
if($checkuser[user_pin]==$user_pin){
$this->getAddiinfoTable()->update($addi_info);
I think you should create a function that returns associative array from model itself.
May be some of property in "Addiinfo" class be protected/private, so you need to get all property-value of model from inside it.
This one should be in your "Addiinfo" class,
public function getArrayData()
{
return get_object_vars($this);
}
Then call it in update function
public function update($model) {
$data = $model->getArrayData();
$id = (int) $model->id;
$this->tableGateway->update($data, array('id' => $id));
}
How can i set a input filter which is dependent from another input field.
I want to set a form field as required only when the othe form field (checkbox) is selected.
How can i handle this in zf2 ?
I use the same idea as Crisp but I prefer to do it in the Form classes instead of the controller. I think it's better to have all validators defined all together in the same place. I do it this way:
1 - All Form classes inherits from a custom BaseForm:
class BaseForm extends ProvidesEventsForm
{
private $postData;
protected function getPostData() {
return $this->postData;
}
public function __construct( $name = null, $serviceManager ) {
parent::__construct( $name );
$this->serviceManager = $serviceManager;
$this->request = $serviceManager->get( 'Application' )->getMvcEvent()->getRequest();
$this->postData = get_object_vars( $this->request->getPost() );
}
}
This way you can easily pick any value from the post, like your checkbox (you can do the same approach with the route parameters, so you'll have all the view data in your Form).
2 - In the FormEdit class that inherits from BaseForm, you pass the getPostData() value to the SomeFilter this way:
class FormEdit extends BaseForm
{
public function __construct( $name = null, $serviceManager ) {
parent::__construct( $name, $serviceManager );
$filter = new SomeFilter( $this->getPostData() );
$this->setInputFilter( $filter );
}
3 - And now just use it in the SomeFilter:
class SomeFilter extends InputFilter
{
public function __construct( $postData ) {
if ( $postData[ 'checkbox' ] ) {
$this->add( array(
'name' => 'other_input',
'required' => true,
) );
}
}
}
This way you keep the Controller clean and all the validators in the same place.
You could test if the checkbox is populated and setValidationGroup accordingly on the form before validating it in your controller action...
public function someAction()
{
$form = new MyForm; // contains name, title, checkbox, required_if_checked fields
// usual form related setup
if ($request->isPost()) {
$form->setData($request->getPost());
// see if the checkbox is checked
$checked = $this->params()->fromPost('checkbox', false);
// not checked, set validation group, omitting the dependent field
if (!$checked) {
$form->setValidationGroup(array(
'name',
'title',
'checkbox', // could probably skip this too
));
}
if ($form->isValid()) {
// do stuff with valid data
}
}
}
i have two tables users and userslog where i have users contains id, username,email,gender and userslog contains id,firstname,lastname,designation and u_id which is foreign key of users table.
my register controller
class RegisterController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$form = new Application_Form_register();
$this->view->form = $form;
if($this->getRequest()->isPost())
{
$data = $this->getRequest()->getPost();
}
}
}
my register model is
class Application_Model_DBtable_register extends Zend_Db_Table
{
protected $_name = 'users';
// i have to define two tables here!! how?
}
my register zend form
class Application_Form_register extends Zend_Form
{
public function init()
{
$this->setName('register');
$this->setMethod('post');
$firstname = $this->createElement('text', 'firstname');
$firstname->setLabel('FirstName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$lastname = $this->createElement('text', 'lastname');
$lastname->setLabel('LastName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$email = $this->createElement('text', 'email');
$email->setLabel('Email: ')
->setRequired(true);
$username = $this->createElement('text', 'username');
$username->setLabel('UserName: ')
->setRequired(true)
->setFilters(array(
'stringTrim','StringToLower'));
$password = $this->createElement('password', 'password');
$password->setLabel('Password: ')
->setRequired(true);
$password2 = $this->createElement('password', 'password2');
$password2->setLabel('Confirm Password: ')
->setRequired(true);
$submit = $this->createElement('submit', 'register');
$submit->setLabel('Register')
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$email,
$username,
$password,
$password2,
$submit));
}
}
how can i do it? can we use Zend_Auth for authentication? if yes then how.please give me example. I saw $_dependantTable and $_referenceMaps but i can't undestand it . I am confused how to do it because i am not able to define table name more than once in a class. i have to insert the values at same time in two different tables.
So as to insert values in users and userslog tables, you can try it:
In your RegisterController:
$db = new Application_Model_DBtable_register();
$db->instertValuesInUsers(array('column_name' => $data['value'], 'column_name' => $data['value'], ...........));
$db->insertValuesInUserslog(array('column_name' => $data['value'], 'column_name' => $data['value'], ...........));
In you Application_Model_DBtable_register:
public function instertValuesInUsers(array $data) {
$this->insert($data);
}
public function insertValuesInUserslog(array $data) {
$db = new Zend_Db_Table(array('name' => 'userslog'));
$db->insert($data);
}
ok this is incorrect:
class Application_Model_DBtable_register extends Zend_Db_Table
{
protected $_name = 'users';
// i have to define two tables here!! how?
}
The intent of classes that have DbTable in their names is that they they are the adapter/gateway to a single database table.
So your issue would breakdown into at least 2 classes/files:
class Application_Model_DBtable_Users extends Zend_Db_Table
{
protected $_name = 'users';
}
class Application_Model_DBtable_Userslog extends Zend_Db_Table
{
protected $_name = 'userslog';
}
I would at this level put a method in either class that does the actions required to register a user. Later you may decide to use mappers and domain objects.
class Application_Model_DBtable_Users extends Zend_Db_Table
{
protected $_name = 'users';
/*
* psuedocode not meant for production
*/
public function register($array $data) {
//sort out the data
$user = array();//put the elements from the $data array that you want to go into the users table
$userLog = array(); //same thing for the userslog table
//get userslog adapter
$userlogTable = new Application_Model_DbTable_Userslog();
//do the first insert
$result = $this->insert($user);
//insert returns the primary key of the row created,
$u_id = array('u_id' => $result);
$userLog = array_merge($u_id, $userLog); //merge u_id with existing data
//perform second insert
$result2 = $userlogTable->insert($userLog);
//handle any errors
}
}
This should provide a basic example to demonstrate the steps you might take to implement you design. The point behind the DbTable models is to abstract the connection to a given table, each table has it's own DbTable model. The DbTable model provides an adapter to each table and access to the api provided by Zend_Db_Table_Abstract.
The Steps shown above could just as easily be taken in a third model or in the controller itself.
Note: There may be away to do this with one sql statement but I'm not the person who knows that answer.
Thanks in advance...see below the code.. i have 2 models, category and product
my product model
class Admin_Model_Product extends Zend_Db_Table_Abstract {
protected $_name = 'products';
protected $_referenceMap = array(
'category' => array(
'columns' => array('category_id'),
'refTableClass' => 'Admin_Model_Category',
'refColumns' => array('id'),
'onDelete' => self::CASCADE,
'onUpdate' => self::RESTRICT
)
);
}
my category model is:
class Admin_Model_Category extends Zend_Db_Table_Abstract {
protected $_name = 'categories';
protected $_dependentTables = array('Admin_Model_Product');
}
in my products controller i have
class Admin_ProductsController extends Zend_Controller_Action {
public function init() {
}
public function indexAction() {
echo '<pre>';
$model = new Admin_Model_Product();
}
}
What i need to do is get all the products using fetchAll() method and need to get parentrow of each product and display it in my view... i can pull all the products but i dont know how to find each products parent category and bind them, is there any example source code? or any suggestion ? i need an array containg all products and parent category name ..please be quick.thanks
Best way to accomplish this would be iterating over products result and creating array containg all categories_ids, then query the Category Model with where('category_id IN (?)', $array_of_categories_ids) and then creating an array from categories rowset with id_category => row_pairs. Then You can do this in just two queries :)
$categories_ids = array();
foreach ($products as $product)
{
$categories_ids[ $product->category_id ] = $product->category_id; // set key to category id to avoid duplicated category' ids
}
$categories = $categoryModel->fetchAll($categoryModel->select()->where('id_category in (?)', $categories_ids)); // here u have to add check on array 'coz if empty it will thoro Query exception
// now just iterate over categories
$categories = array();
foreach ($categories as $category)
{
$categories[ $category->id_category ] = $category;
}
// now when iterating over products u can just do $categories[ $product->category_id ] to get proper category for profuct
Anyway sorry for possible typos, wrote it on the fly ;)
try the following :
retrieve categories and their products :
$model_category = new Admin_Model_Category();
$categorySet = $model_category->fetchAll();
$categories = $categorySet->toArray();
$i = 0;
$results = array();
foreach($categories as $category)
$categoryRow = $model_category->fetchRow('id =', $category->category_id)
$products = $categoryRow->findDependentRowset('Admin_Model_Product');
$results[$i]['parent'] = $category;
$results[$i]['products'] = $products;
$i++;
}
then pass it to the view:
$view->results = results;
I'm using Doctrine 2 in a Zend Framework application and require functionality similar to Zend_Validate_Db_RecordExists and Zend_Validate_Db_NoRecordExists.
For example, when a user enters a new item, I need to validate that a duplicate entry doesn't already exist. This is easy to accomplish with Zend_Db by adding the Db_NoRecordExists validator on my forms.
I tried implementing the custom-validator solution proposed here, but I can't figure out how they are communicating with Doctrine to retrieve entities (I suspect this approach may no longer work post-Doctrine 1.x).
The FAQ section of the Doctrine manual suggests calling contains() from the client code, but this only covers collections, and if possible I'd like to handle all of my form validation consistently from within my form models.
Can anyone suggest a way to use these Zend validators with Doctrine 2 DBAL configured as the database connection/resource?
It's quite straightforward, really.
I have a few Zend_Validate-type validators that talk to Doctrine ORM, so I have an abstract class that they descend from.
Here's the abstract class:
<?php
namespace TimDev\Validate\Doctrine;
abstract class AbstractValidator extends \Zend_Validate_Abstract{
/**
* #var Doctrine\ORM\EntityManager
*/
private $_em;
public function __construct(\Doctrine\ORM\EntityManager $em){
$this->_em = $em;
}
public function em(){
return $this->_em;
}
}
Here's my NoEntityExists validator:
<?php
namespace TimDev\Validate\Doctrine;
class NoEntityExists extends AbstractValidator{
private $_ec = null;
private $_property = null;
private $_exclude = null;
const ERROR_ENTITY_EXISTS = 1;
protected $_messageTemplates = array(
self::ERROR_ENTITY_EXISTS => 'Another record already contains %value%'
);
public function __construct($opts){
$this->_ec = $opts['class'];
$this->_property = $opts['property'];
$this->_exclude = $opts['exclude'];
parent::__construct($opts['entityManager']);
}
public function getQuery(){
$qb = $this->em()->createQueryBuilder();
$qb->select('o')
->from($this->_ec,'o')
->where('o.' . $this->_property .'=:value');
if ($this->_exclude !== null){
if (is_array($this->_exclude)){
foreach($this->_exclude as $k=>$ex){
$qb->andWhere('o.' . $ex['property'] .' != :value'.$k);
$qb->setParameter('value'.$k,$ex['value'] ? $ex['value'] : '');
}
}
}
$query = $qb->getQuery();
return $query;
}
public function isValid($value){
$valid = true;
$this->_setValue($value);
$query = $this->getQuery();
$query->setParameter("value", $value);
$result = $query->execute();
if (count($result)){
$valid = false;
$this->_error(self::ERROR_ENTITY_EXISTS);
}
return $valid;
}
}
Used in the context of a Zend_Form (which has an em() method like the abstract class above):
/**
* Overrides superclass method to add just-in-time validation for NoEntityExists-type validators that
* rely on knowing the id of the entity in question.
* #param type $data
* #return type
*/
public function isValid($data) {
$unameUnique = new NoEntityExists(
array('entityManager' => $this->em(),
'class' => 'PMS\Entity\User',
'property' => 'username',
'exclude' => array(
array('property' => 'id', 'value' => $this->getValue('id'))
)
)
);
$unameUnique->setMessage('Another user already has username "%value%"', NoEntityExists::ERROR_ENTITY_EXISTS);
$this->getElement('username')->addValidator($unameUnique);
return parent::isValid($data);
}
Check out the RecordExists.php and NoRecordExists.php classes in my project:-
https://github.com/andyfenna/AJF-IT/tree/master/library/AJFIT/Validate
I hope these are some use to you.
Thanks
Andrew