During saving I recive an error:
values() expects an array of values or Zend\Db\Sql\Select instance
I think error comes from:
$this->tableGateway->insert($procedure);
I don't understand what is wrong.
This is my process function:
public function processAction()
{
if (!$this->request->isPost()){
return $this->redirect()->toRoute(null, array('controller'=>'test', 'action'=>'index'));
}
$post = $this->request->getPost();
$form = new TestForm();
$inputFilter = new \Postepowania\Form\TestFilter();
$form->setInputFilter($inputFilter);
$form->setData($post);
if (!$form->isValid()){
$model = new ViewModel(
array(
'error' => true,
'form' =>$form,
)
);
$model->setTemplate('postepowania/test/index');
return $model;
}
$this->createTest($form->getData());
//return $this->redirect()->toRoute(null,array('controller' => 'test','action' => 'confirm',));
}
and createTest function:
public function createTest(array $data){
$testTable = $this->getServiceLocator()->get('TestTable');
$test = new Test();
$test->exchangeArray($data);
$testTable->save($test);
return true;
}
Save function is very simple:
public function save(Test $procedure)
{
$id = (int)$procedure->id;
if($id == 0)
{
$this->tableGateway->insert($procedure);
}
}
$this->tableGateway->insert()
From looking at the source, insert() requires an array to be passed into it, not an object. I suggest converting your object to an array before passing it in.
Related
I want my form fields to contain the previous data contained in database when the form page opens. I went through lots of queries here and came to know using populate() or bind() method is the way to do it. But when I try to use it, I get an undefined method error.
Is there any other way to do it?
I am unable to use bind() as well. I am getting a fresh form with default values after I submit.
Sorry if this is a stupid question. Its been only 4-5 days since I started learning Zend framework. Also, most of the methods I get online are for older frameworks. I am using Zend Framework2.
This is Controller Code
<?php
class ChatController extends AbstractActionController
{
protected $chatTable;
public function indexAction()
{
$form = new ChatForm();
$model= new Chat();
$form->bind($model);
$form->get('submit')->setValue('Save');
$request = $this->getRequest();
if ($request->isPost()) {
$gen_set = new Chat();
$form->setInputFilter($gen_set->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$gen_set->exchangeArray($form->getData());
$this->getChatTable()->saveChat($gen_set);
// Redirect to list of albums
return $this->redirect()->toRoute('chat');
}
}
return array('form' => $form);
}
public function getChatTable()
{
if (!$this->chatTable) {
$sm = $this->getServiceLocator();
$this->chatTable = $sm->get('Chat\Model\ChatTable');
}
return $this->chatTable;
}
}
My Entity Class, Here api_key and anon_prefix are rows of the column 'settings' and there is one more column with value.
<?php
class Chat implements InputFilterAwareInterface
{
protected $inputFilter;
public function exchangeArray($data)
{
$this->api_key=(isset($data['api_key'])) ? $data['api_key'] : null;
$this->anon_prefix = (isset($data['anon_prefix'])) ? $data['anon_prefix'] : null;
}
// Add content to these methods:
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'iflychat_external_api_key',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
));
$inputFilter->add(array(
'name' => 'iflychat_show_admin_list',
'required' => true,
'validators' => array(
array(
'name' => 'InArray',
'options' => array(
'haystack' => array(1,2),
),
),
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
public function getArrayCopy()
{
return get_object_vars($this);
}
}
This is used to enter values into db
<?php
class ChatTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function saveChat(Chat $gen_set)
{
$data = array(
'value' => $gen_set->api_key,
);
$id='iflychat_external_api_key';
$this->tableGateway->update($data,array('settings' => $id));
$data = array(
'value' => $gen_set->anon_prefix,
);
$id='anon_prefix';
$this->tableGateway->update($data,array('settings' => $id));
}
}
I am getting this error, 'Cannot use object of type Chat\Model\Chat as array'
Your action doesn't make much sense as it is, you instantiate a Chat instance as $model and later another instance as $gen_set. What you should be doing is binding the first one, and using the form class getData method to later return the instance you bound to it, along with the values you gave it in the setData method. There's no need for any transformations from object to array and back again.
Here's how it should look ...
public function indexAction()
{
$form = new ChatForm();
// bind the model
$model= new Chat();
$form->bind($model);
$form->get('submit')->setValue('Save');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($gen_set->getInputFilter());
// set data from POST as properties of the bound model ...
$form->setData($request->getPost());
if ($form->isValid()) {
// get the bound model instance with the POSTed values
// ($gen_set is now the original $model object instance bound above)
$gen_set = $form->getData();
// and save it
$this->getChatTable()->saveChat($gen_set);
// Redirect to list of albums
return $this->redirect()->toRoute('chat');
}
}
return array('form' => $form);
}
Controller Code -
<?php
class ChatController extends AbstractActionController {
protected $chatTable;
public function indexAction() {
$model = $this->getChatTable()->fetchLastChat();
if($model === null || $model->count() == 0)
$model = new Chat();
//Now if no record exists in the database then $model will be empty
//Else $model will contain data of last record.
$form = new ChatForm();
$form->bind($model);
$form->get('submit')->setValue('Save');
$request = $this->getRequest();
if ($request->isPost()) {
$gen_set = new Chat();
$form->setInputFilter($gen_set->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$gen_set->exchangeArray($form->getData());
$this->getChatTable()->saveChat($gen_set);
}
}
return array('form' => $form);
}
public function getChatTable() {
if (!$this->chatTable) {
$sm = $this->getServiceLocator();
$this->chatTable = $sm->get('Chat\Model\ChatTable');
}
return $this->chatTable;
}
}
ChatTable Class Code -
<?php
//Other use statements
use Zend\Db\Sql\Select;
class ChatTable {
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function fetchAll() {
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function fetchLastChat() {
$select = new Select('TABLE_NAME'); //Change the tablename accordingly
$select->order('PRIMARY_KEY DESC'); //Set the Primary Key of the table
$select->limit(1);
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet->current();
}
//Rest of the Code ....
Please take the idea from the above code.
I am trying to implement View Strategy in ZF2.
As far as the basic setup, everything seem to be working fine except that ViewEvent Renderer is always null, thus the renderer never gets injected to the Strategy, and TemplateResolver still requests a template and displays the following error.
PhpRenderer::render: Unable to render template "api/api/get"; resolver could not resolve to a file'
I have even tried to copy the code JsonModel and JsonStrategy from ZF2, and still get the same result.
ViewYamlStrategy.php
public function selectRenderer(ViewEvent $e)
{
$renderer = $e->getRenderer(); // Always return null
}
module.php
public function getServiceConfig()
{
return ['factories' => [
'ViewYamlRenderer' => "Namespace\Mvc\Service\ViewYamlRendererFactory",
'ViewYamlStrategy' => "Namespace\Mvc\Service\ViewYamlStrategyFactory",
],
];
}
module.config.php
'view_manager' => [
'strategies' => [
'ViewYamlStrategy'
],
],
controller
public function getList()
{
return new YamlModel($data);
}
ViewYamlStrategy.php
function __construct(ViewYamlRenderer $renderer)
{
$this->renderer = $renderer;
}
public function attach(EventManagerInterface $events, $priority = 1)
{
$this->listeners[] = $events->attach(ViewEvent::EVENT_RENDERER, [$this, "selectRenderer"], $priority);
$this->listeners[] = $events->attach(ViewEvent::EVENT_RESPONSE, [$this, "injectResponse"], $priority);
}
public function selectRenderer(ViewEvent $e)
{
$renderer = $e->getRenderer();
if ($this->renderer !== $renderer) {
return;
}
}
public function injectResponse(ViewEvent $e)
{
$renderer = $e->getRenderer(); // Always null
if ($this->renderer !== $renderer) {
return;
}
$result = $e->getResult();
$response = $e->getResponse();
$response->setContent($result);
}
ViewYamlRenderer.php
public function render($nameOrModel, $values = null)
{
return $nameOrModel->serialize();
}
public function setResolver(\Zend\View\Resolver\ResolverInterface $resolver)
{
$this->resolver = $resolver;
}
YamlModel.php
protected $captureTo = null;
protected $terminate = true;
public function serialize()
{
/*Serialize Object and return a string*/
}
thanks
I think this is due to the order that the strategies/listeners are triggered; As once a ViewRender is found the event propagation is halted and that renderer is returned.
It seems that the standard PhpRenderStrategy has a default event priority of 1 and the others (JsonStrategy etc) seem to fire prior to this (with an even priority of 100)
Try changing the $priority; perhaps 101
$this->listeners[] = $events->attach(
ViewEvent::EVENT_RENDERER,
[$this, "selectRenderer"],
101 // <-- change here
);
I have finally found the issue.
ViewYamlStrategy.php
/* This should return a renderer */
public function selectRenderer(ViewEvent $e)
{
// here I was checking the Renderer which was not created yet
// and instead I should've checked the model
$model = $e->getModel();
if (!$model instanceof YamlModel) {
return;
}
return $this->renderer;
}
I've got a fatal error when I intent insert a row in DB. I don't understand what's happening, I readed some blogs but there is not a solution, my code is the same like an example publicated by Evan in his blog.
My model class
class CommentTable
{
protected $_commentTableGateway;
protected $_hydratator;
protected $_resultSet;
public function __construct($adapter)
{
$this->_hydratator = new \Zend\Stdlib\Hydrator\ClassMethods;
$rowObjectPrototype = new Comment();
$this->_resultSet = new \Zend\Db\ResultSet\HydratingResultSet($this->_hydratator, $rowObjectPrototype);
$this->_commentTableGateway = new TableGateway('comments', $adapter, null, $this->_resultSet );
}
public function fetchAll()
{
return $this->_commentTableGateway->select();
}
public function saveComment(Comment $comment)
{
$id = (int)$comment->getId();
if ($id == 0) {
$this->_commentTableGateway->insert($this->_hydratator->extract($comment));//this fails
} else {
if ($this->getComment($id)) {
$this->_commentTableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('El comentario que queire editar no exite');
}
}
}
public function getComment($id)
{
$id = (int) $id;
$rowset = $this->_commentTableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
}
</code>
<code>
In module class:
//a factory in service manager
'Comment\Model\CommentTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new CommentTable($dbAdapter);
return $table;
},
</code>
<code>
My controller:
public function getCommentTable()
{
if (!$this->_commentTable) {
$sm = $this->getServiceLocator();
$this->_commentTable = $sm->get('Comment\Model\CommentTable');
}
return $this->_commentTable;
}
</code>
And I get this error:
Catchable fatal error: Object of class stdClass could not be converted to string in D:\xampp\htdocs\haystack\vendor\zendframework\zendframework\library\Zend\Db\Adapter\Driver\Pdo\Statement.php on line 258
I know the type of the error('stdClass could not be converted to string'), but I don't understand what's happening...
Any help is appreciated
Kind regards.
Hopefully this will help you out. Here is my TableGateway
class Domains extends AbstractTableGateway
{
public function __construct($adapter)
{
$this->table = 'domains';
$this->adapter = $adapter;
$this->initialize();
}
}
And here is how I insert data:
$this->getTableDomains()->insert(array(
'companyid' => $params['companyid'],
'domain_id' => $result->id,
'name' => $name,
'type' => strtoupper($params['type']),
'content' => strtolower($params['content']),
'ttl' => $ttl,
'prio' => $prio
));
I got a ZF2 project with 2 Models PosTable/TopTable which extend AbstractTableGateway.
I want to Paginate results from those Tables so i have a Pagination function in both of them.
this is what the PosTable Model looks like:
...
class PosTable extends AbstractTableGateway {
public function __construct($adapter) {
$this->table = 'pos';
$this->adapter = $adapter;
}
...
public function getPosPaginator($tid) {
$sql = $this->getSql();
$select = $sql->select();
$select->where('tid = '.$tid)->where('deleted = 0')->order('crdate ASC');
$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $sql);
$paginator = new \Zend\Paginator\Paginator($adapter);
return $paginator;
}
...
which works perfectly.
but in my TopTable it looks the same like this:
...
class TopTable extends AbstractTableGateway {
public function __construct($adapter) {
$this->table = 'top';
$this->adapter = $adapter;
}
public function getTopPaginator($fid) {
$sql = $this->getSql();
$select = $sql->select();
$select->where('fid = '.$fid)->where('deleted = 0');
$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $sql);
$paginator = new \Zend\Paginator\Paginator($adapter);
return $paginator;
}
...
my controller looks like this for PosTable:
...
public function posAction(){
...
$pos = $this->getPosTable()->getPosPaginator($tid);
$pos->setCurrentPageNumber($pageid)->setItemCountPerPage(19);
... return $pos etc...
same controller topAction:
...
public function topAction(){
...
$top = $this->getTopTable()->getTopPaginator($fid);
$top->setCurrentPageNumber($pageid)->setItemCountPerPage(20);
...return $top etc..
in that controller i got also these functions:
public function getTopTable(){
return $this->getServiceLocator()->get('Application\Model\TopTable');
}
public function getPosTable(){
return $this->getServiceLocator()->get('Application\Model\PosTable');
}
PosTable Pagination works perfectly, but the TopTable Pagination doesnt work.
i get this error:
Fatal error: Call to a member function select() on a non-object in ....
seems like
$sql = $this->getSql();
doesnt return the object.
how can i solve this problem?
one works one doesnt for no obvious reason.
my module.php looks like this:
namespace Application;
class Module
{
public function getAutoloaderConfig()
{
return array('Zend\Loader\StandardAutoloader' =>
array('namespaces' =>
array(__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Model\TopTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Application\Model\TopTable($dbAdapter);
return $table;
},
'Application\Model\ForTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Application\Model\ForTable($dbAdapter);
return $table;
},
'Application\Model\PosTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new \Application\Model\PosTable($dbAdapter);
return $table;
},
),
);
}
}
Ok, after going through TableGateway Code and your extended class, I found the your implementation is not calling initialize which setup the sql object try to call the parent table gateway, below is the modified constructor for your PosTable and TopTable
/* for PosTable */
class PosTable extends TableGateway {
public function __construct($adapter) {
parent::__construct('pos', $adapter);
}
...
/* for TopTable */
class TopTable extends TableGateway {
public function __construct($adapter) {
parent::__construct('top', $adapter);
}
...
I use symfony 1.4.11 .I have next component class:
class companiesComponents extends sfComponents {
public function executeCompanylist(sfWebRequest $request) {
// And the URL
if (!isset($this->url)) {
throw new Exception('Please specify the URL');
}
// Save the page
if ($request->getParameter('page')) {
$this->setPage($request->getParameter('page'));
}
// Create pager
$this->pager = new sfDoctrinePager('Companies', sfConfig::get('app_ads_per_page', 5));
$this->pager->setQuery($this->query);
$this->pager->setPage($this->getPage());
$this->pager->init();
}
protected function getPager($query) {
$pager = new Doctrine_Pager($query, $this->getPage(), 3);
return $pager;
}
protected function setPage($page) {
$this->getUser()->setAttribute('users.page', $page, 'admin_module');
}
protected function getPage() {
return $this->getUser()->getAttribute('users.page', 1, 'admin_module');
}
I have action:
public function executeAll(sfWebRequest $request)
{
$this->query = Doctrine_Core::getTable('Companies')->getAllCompany();
$this->url = '#companylist';
}
And I have allSucess.php
<?php include_component('companies', 'companylist', array(
'query' => $query,
'url' => $url,
'noneFound' => __('You haven\'t created any ads yet.')
)) ?>
In my Companies Table class
public function getAllCompany()
{
$q = $this->createQuery('a')
->andWhere('a.active = ?',1)
->leftJoin('a.Owner o')
->leftJoin('o.Profile p')
->andWhere('p.payed_until > NOW()')
->addORDERBY ('created_at DESC');
}
And it is do not work. I get all my record "companies" from database,but they are not selected according to the my query...
When I make
public function getAllCompany()
{
}
or when I comment
// $this->pager->setQuery($this->query);
I still get all my records :(
In logs I see :
Template: companies … allSuccess.php
Parameters:
$query (NULL)
$url (string)
When I make
public function getAllCompany()
{
$q = $this->createQuery('a')
->andWhere('a.active = ?',1)
->leftJoin('a.Owner o')
->leftJoin('o.Profile p')
->andWhere('p.payed_until > NOW()')
->addORDERBY ('created_at DESC');
return $q->execute();
}
I have error:
Fatal error: Call to undefined method Doctrine_Collection::offset()
I do not understand how it get all records, and where I made mistake :(
Thank you!
remove the ->execute(); text from the return statement in the getAllCompany() function ... the DoctrinePager executes the statement - you don't need to ...
public function getAllCompany()
{
$q = $this->createQuery('a')
->andWhere('a.active = ?',1)
->leftJoin('a.Owner o')
->leftJoin('o.Profile p')
->andWhere('p.payed_until > NOW()')
->addOrderBy('created_at DESC');
return $q;
}