Symfony form with doctrine table other than getTable()->find() is not working - forms

I get a really anoying error when I try to edit an entry from a table, in tutorial they always use getTable()->find(), but I need to verify that the person logged in is the owner of that entry here what I did:
In the action:
public function executeEdit(sfWebRequest $request)
{
$id = $request->getParameter('id');
$userid = $this->getUser()->getGuardUser()->getId();
$ad = Doctrine_Core::getTable('BambinbazarArticles')->getMyAd($id, $userid);
$this->forward404Unless($ad, sprintf('Object bambinbazar_articles does not exist (%s).', $request->getParameter('id')));
$this->form = new BambinbazarArticlesForm($ad);
}
In the model:
public function getMyAd($id, $userid)
{
$q = $this->createQuery('c')
->where('c.id = ? ', $id)
->addWhere('c.userid = ? ', $userid);
return $q->execute();
}
I tried it with and without the ->execute(), did doctrine clean, cleared cache, rebuilded model,
Always get the same error 'The "%s" form only accepts a "%s" object.
If I use the Doctrine_Core::getTable('BambinbazarArticles')->find() it work, but of course, i need more than that..
I am becoming crazy over this.

execute() can return multiple rows; effectively you're getting a recordset back, rather than the individual object that your form is expecting. Try fetching a single object, using, e.g.:
return $q->execute()->getFirst();
or
return $q->fetchOne();

Its probably because your query is returning a Doctrine_Collection, not the actual Doctrine_Record youre expecting. Instead of execute use fetchOne.
public function getMyAd($id, $userid)
{
$q = $this->createQuery('c')
->where('c.id = ? ', $id)
->addWhere('c.userid = ? ', $userid)
->limit(1);
return $q->fetchOne();
}

Related

Is it possible to declare a form object inside a block of if condition in zend framework?

I am very new to zend framework. I want to declare a form object inside an if condition. but I don't know is it possible or not ?. I write the below code:
public function editAction()
{
$modelUsers = new Model_Users();
$userId = $this->_getParam('userId');
if ($userId) {
$populateData = array();
$user = $modelUsers->fetch($userId);
// print_r($user); exit();
if ($user instanceof Model_User) {
$populateData = $user->toArray();
$form = $this->_geteditForm($user->email);
}
$form->populate($populateData);
}
$request = $this->getRequest();
if ($request->isPost()) {
Please let me know I am going to the write path or not.
Thanks in advance
It's OK, but (assuming that it's some kind of a crud) it's better to redirect back to list or throw exception if the ID is missing. Than you don't need to close the whole form in condition. i.e:
if (!$userId = $this->_getParam('userId')) {
throw new Exception('Missing userId');
//or
$this->_helper->redirector('index');
}

Zend Paginate - find a specific record within the result

I appreciate that this may not be possible, but is there a way to make Zend Paginate go to a specific item (record)?
The result I would like would allow me to seek a specific record in a tabled list of results, and display the appropriate page (within all available pages) combined with a name anchor tag to display the specific record.
To clarify: If I had the results as a Zend_Db_Table_Rowset_Abstract I would use the seek() method in a similar fashion to $rowset->seek(8); Although I don't believe the result returned by the DbSelect adapter is a SeekableIterator?
The code within my Mapper (using the Table Data Gateway pattern):
public function paginate($where = array(), $order = null)
{
$select = $this->getDbTable()->select()->from($this->getTableName(), $this->getTableFields());
foreach ($where as $key => $value) {
$select->where($key, $value);
}
$select->order($order);
$adapter = new Zend_Paginator_Adapter_DbSelect($select);
$paginator = new Zend_Paginator($adapter);
return $paginator;
}
Within my controller:
$cache_id = sha1('list');
$mapper = new Application_Model_Galleries_Mapper();
if(!($data = Zend_Registry::get('cache')->load($cache_id))) {
$data = $mapper->paginate(array(), $sort);
Zend_Registry::get('cache')->save($data, $cache_id, array('list'), 7200);
}
$data->setCurrentPageNumber($this->_getParam('page'));
$data->setItemCountPerPage(30);
$this->view->paginator = $data;
To return a Zend_Paginator with a seekable iterator (Zend_Db_Table_Rowset) use the Zend_Paginator_Adapter_DbTableSelect() as it returns a rowset object, as opposed to Zend_Paginator_Adaoter_DbSelect() which returns an array().
Zend_Paginator

Zend Db query to select all IDs

How would I write an Zend DB query to select all from the column ID?
So far I have tried:
public function getLatestUserID()
{
$ids = $this->select()
->where('id = ?');
return $ids;
}
But to no avail.
You just want the id column,
You failed to call an execute command.
try:
//assuming you are using a DbTable model
public function getLatestUserID()
{
$ids = $this->fetchAll('id');
return $ids;
}
I would do it like this, because I use the select() object for everything:
public function getLatestUserID()
{
$select = $this->select();
//I'm not sure if $this will work in this contex but you can out the table name
$select->from(array($this), array('id'));
$ids = $this->fetchAll($select);
return $ids;
}
The first two examples should return just the id column of the table, now if you actually want to query for a specific id:
public function getLatestUserID($id)
{
$select = $this->select();
$select->where('id = ?', $id);
//fetchAll() would still work here if we wanted multiple rows returned
//but fetchRow() for one row and fetchRowset() for multiple rows are probably
//more specific for this purpose.
$ids = $this->fetchRow($select);
return $ids;
}
make sure your class containing getLatestUserID does extend Zend_Db_Table_Abstract also :
$ids = $this->select()->where('id = ?'); can't work because where('id = ?'); expects an id value like where('id = ?', $id);
if what you want is the latest inserted row's Id use :
$lastInsertId = $this->getAdapter()->lastInsertId();
(however if you are using an oracle database this will not work and you should use $lastInsertId = $this->getAdapter()->lastSequenceId('USER_TABLE_SEQUENCE'); )

Zend Framework, echo message if (!$row) not working

This should be straight forward if the row count is 0 I want to echo a message. Here is what I have:
public function getClubComment($id) {
$id = (int) $id;
$row = $this->fetchRow('club_id = ' . $id);
if (!$row) {
echo 'No comments';
}
return $row->toArray();
var_dump($row);
}
maybe try something like:
//not sure if this will work as I don't do this kind of request anymore
public function getClubComment($id) {
$id = (int) $id;
$row = $this->fetchRow('club_id = ?', $id);
if (!$row) {echo 'No comments';}
return $row->toArray();
var_dump($row);
}
I think you'll be happier doing something like this, takes most of the guess work out.
public function getClubComment($id) {
$id = (int) $id;
//create instance of Zend_Db_Select object
$select = $this select();
$select->where('club_id = ?', $id);
//fetchRow using Zend_Db_Select object
$row = $this->fetchRow($select);
//fetchRow() returns NULL so may as well test for that.
if ($row === NULL) {
throw new Zend_Db_Table_Exception();
}
return $row->toArray();
var_dump($row);
}
Zend_Db_Select is really useful to use in the models as it normally takes care of properly quoting values and it very easy to build a fairly complex sql query with any sql. In this example I used discrete lines for each part of the select() but I could as easily have strung them all together. I personally like each line separate so I can change or troubleshoot easily.
fetchRow returns an object, even if there is no results, that is why the condition in the if statement is always false, try this
if (!count($row))

Symfony: question about the form filters

In the frontend I have a page with a list and a form filter next to it
that shows all the users of a social network.
I would like to hide the user of the session in that list. How can I
do it?
My first thought is creating a function, addXXXXColumnQuery(), for each
field of the form, and in each one add a line like this:
->andWhere("u.id <> ?", $id)
$id being the ID of the user of the current session. But in that way I
find I'm repeating myself.
What should I do?
First, you need to get the user into the filter. You have two options:
Pass the user_id in as an option when you instantiate the form, inside the action:
public function executeList(sfWebRequest $request)
{
$user_id = $this->getUser()->getUserId();
$filter = new ModelFormFilter(array(), array('user_id' => $user_id));
...
Get the user id from the context inside of the form:
sfContext::getInstance()->getUser()->getUserId();
I prefer the former method because it's cleaner and less WTFy.
Once you have the user id, override doBuildQuery to exclude the current user id inside of your FormFilter:
protected function doBuildQuery(array $values)
{
$query = parent::doBuildQuery($values);
$user_id = $this->getOption('user_id'); //or off the context here
if ($user_id)
{
$query->addWhere('r.user_id != ?', $user_id);
}
return $query;
}