I am attempting to extend the Zend Framework Quickstart tutorial by trying to make an individual view for each guestbook entry, but I am missing something and keep getting errors like:
Trying to get property of non-object in C:\wamp\www\quickstart.local\application\views\scripts\guestbook\display.phtml
I get this when trying the following for my displayAction and my display.phtml:
//view
<p><?php echo $this->escape($this->entry->id); ?></strong> <a><?php echo $this->escape($this->entry->comment); ?></a><br>
<?php echo $this->escape($this->entry->email); ?></p>
//action
public function displayAction()
{
$id = $this->getRequest()->getParams('id');
$entry = new Application_Model_GuestbookMapper();
$this->view->entry = $entry->find($id);
}
And the find() function in the mapper is as is from the tutorial.
I have look all over the web and have only found tutorials that omit the quickstart guide's structure altogether. While they are all solid in their own right, I would like to find a solution to this. What am I doing wrong?
I am about mid-level with php and a beginner with zend framework. Please keep that in mind when responding.
If you're following the quickstart verboten, you'll want something like this
public function displayAction()
{
$id = $this->getRequest()->getParam('id');
$model = new Application_Model_Guestbook;
$mapper = new Application_Model_GuestbookMapper;
$mapper->find($id, $model);
if (null === $model->getId()) {
throw new Zend_Controller_Action_Exception(
sprintf('Guestbook entry %d not found', $id), 404);
}
$this->view->entry = $model;
}
in order to use GuestbookMapper with the Find() method you need to supply two items of information to the method, the id and an instance of Guestbook. The instance of guestbook is required because it has all the getters and setters mapper uses to generate the returned data.
//action updated
public function displayAction()
{
$id = $this->getRequest()->getParams('id');
$guestbook = new Application_Model_GuestBook();
$entry = new Application_Model_GuestbookMapper();
$this->view->entry = $entry->find($id, $guestbook);
}
for a detailed explaination of how this works check out chapter 9 of Survive the Deepend
Related
I need to generate widgets\ActiveForm::field() without "form" tag at begin. I looked in source of yii\widgets\ActiveForm and found that this can not be avoided :(
public function init()
{
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
echo Html::beginForm($this->action, $this->method, $this->options);
}
Maybe there's another way to solve this problem without extending the 'ActiveForm' class?
ActiveField is basically just a wrapper for yii\helpers\Html::active... methods so you just can call echo yii\helpers\Html::activeTextInput($model, $attribute, $options); without using ActiveForm
I am trying to use the autocomplete addon in agile toolkit (I am still very much new to this, but it seems to be very well suited for my needs). Autocomplete Basic works, but when I use Plus and press the plus-button I get an error connected to no model set. In the Plus source the self-model should be used - but I don't understand how I should set the model of the autocomplete form.
This is the important part of the stack trace, I think:
Frontend_page_form: Form->setModel(Null)
Frontend_createquestions_form_question_id:
autocomplete\Form_Field_Plus->autocomplete{closure}(Object(Page))
This is my model:
class Model_QuestionInCollection extends Model_Table {
public $entity_code='questionincollection';
function init(){
parent::init();
$this->hasOne('Question')->display(array('form'=>'autocomplete/Plus'));
This is the code:
$form=$this->add('Form');
$form->setModel('QuestionInCollection');
--- EDIT
I ended up changing the model in autocomplete, and now it works, showing that something is wrong in the original "$self->model" - but of course it cannot be generalized. I did some extra changes (to make the new record show up in the autocomplete-field), so Autocomplete/Plus now is like this:
<?php
namespace autocomplete;
class Form_Field_Plus extends Form_Field_Basic
{
function init()
{
parent::init();
$self = $this;
$f = $this->other_field;
// Add buttonset to name field
$bs = $f->afterField()->add('ButtonSet');
// Add button - open dialog for adding new element
$bs->add('Button')
->set('+')
->add('VirtualPage')
->bindEvent('Add New Record', 'click')
->set(function($page)use($self) {
$model=$this->add('Model_Question');
$form = $page->add('Form');
$form->setModel($model); //Was: $self->model
//Would be nice if it worked...: $form->getElement($model->title_field)->set($self->other_field->js()->val());
if ($form->isSubmitted()) {
$form->update();
$js = array();
$js[] = $self->js()->val($form->model[$model->id_field]);
$js[] = $self->other_field->js()->val($form->model[$model->title_field]);
$form->js(null, $js)->univ()->closeDialog()->execute();
}
});
}
}
Here is an example on using autocomplete: http://codepad.demo.agiletech.ie/interactive-views/autocomplete
You can manually create a form and link the field with Model.
If that works fine, you can move on to trying and get your own example working. It seems OK, and should work in theory.
I'm using Zend Framework in combination with Doctrine 2 and mongoDB.
So far so good.
Now I'm rewriting my custom validation class in order to check if a username already exists in the database. (This code worked fine with ORM and MySQL, but not now with ODM and mongoDB).
So my custom validation class looks like this:
<?php
class Project_Validate_UsernameUnique extends Zend_Validate_Abstract {
const USERNAME_EXISTS = '';
protected $_messageTemplates = array (
self::USERNAME_EXISTS => "'%value%' is taken. Please choose another username."
);
public function isValid($value) {
// setting value for the form
$this->_setValue($value);
// get the document manager and repository
$front = Zend_Controller_Front::getInstance();
$dm = $front->getParam('bootstrap')->getResource('odm');
$userRepository = $dm->getRepository('Entities\User');
$user = $userRepository->findOneBy(array('username' => $value));
// if an user was found, return false
if ($user) {
$this->_error(self::USERNAME_EXISTS);
return false;
}
return true;
}
}
But I get this error here:
Warning: file_put_contents(/Applications/XAMPP/xamppfiles/htdocs/project/application/models/Hydrators/EntitiesUserHydrator.php) [function.file-put-contents]: failed to open stream: No such file or directory in /Applications/XAMPP/xamppfiles/htdocs/project/library/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php on line 343
I also tried findBy and without the array annotation (findByUsername or findOneByUsername), but still, either I get this error or somehow "nothing".
With ORM and MySQL it worked perfect, so where is the problem?
Thanks in advance!
Is your Hydrators folder writable by PHP?
What I want to do with Zend Framework is to render the action Y from the action X and to obtain the html:
Example:
public xAction(){
$html = some_function_that_render_action('y');
}
public yAction(){
$this->view->somedata = 'sometext';
}
where the y view is something like:
<h1>Y View</h1>
<p>Somedata = <?php echo $this->somedata ?></p>
I fount the action helper, but I cannot use it from a controller. How can I solve it?
It is possible?
Here is one possible way to do what you want.
public function xAction()
{
$this->_helper
->viewRenderer
->setRender('y'); // render y.phtml viewscript instead of x.phtml
$this->yAction();
// now yAction has been called and zend view will render y.phtml instead of x.phtml
}
public function yAction()
{
// action code here that assigns to the view.
}
Instead of using the ViewRenderer to set the view script to use, you could also call yAction as I showed above, but get the html by calling $html = $this->view->render('controller/y.phtml');
See also the ActionStack helper.
You can use the Action View Helper from the controller
public function xAction()
{
$html = $this->view->action(
'y',
$this->getRequest()->getControllerName(),
null,
$this->getRequest()->getParams()
);
}
public function yAction()
{
// action code here that assigns to the view.
}
It's not very beautiful but it works well and you don't have to use $view->setScriptPath($this->view->getScriptPaths());
This helper creates a new Zend_Controller_Request for yAction(), so you can give your own parameters as 4th argument or use $this->getRequest()->getParams() to spread the request parameters of xAction().
http://framework.zend.com/manual/1.12/en/zend.view.helpers.html#zend.view.helpers.initial.action
Finally I found this "solution", it's not what I want to do, but it works, if someone found the real solution, please answer here.
public function xAction(){
$data = $this->_prepareData();
$view = new Zend_View();
$view->somedata = $data;
$view->setScriptPath($this->view->getScriptPaths());
$html = $view->render('controller/y.phtml');
}
I'm trying to set up a route in Zend Framework (version 1.11.11) in a routes.ini file, which would allow be to match the following url:
my.domain.com/shop/add/123
to the ShopController and addAction. However, for some reason the parameter (the number at the end) is not being recognized by my action. The PHP error I'm getting is
Warning: Missing argument 1 for ShopController::addAction(), called in...
I know I could set this up using PHP code in the bootstrap, but I want to understand how to do this type of setup in a .ini file and I'm having a hard time finding any resources that explain this. I should also point out that I'm using modules in my project. What I've come up with using various snippets found here and there online is the following:
application/config/routes.ini:
[routes]
routes.shop.route = "shop/add/:productid/*"
routes.shop.defaults.controller = shop
routes.shop.defaults.action = add
routes.shop.defaults.productid = 0
routes.shop.reqs.productid = \d+
Bootstrap.php:
...
protected function _initRoutes()
{
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/routes.ini', 'routes');
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addConfig( $config, 'routes' );
}
...
ShopController.php
<?php
class ShopController extends Egil_Controllers_BaseController
{
public function indexAction()
{
// action body
}
public function addAction($id)
{
echo "the id: ".$id;
}
}
Any suggestions as to why this is not working? I have a feeling I'm missing something fundamental about routing in Zend through .ini files.
Apparently I'm more rusty in Zend than I thought. A few minutes after posting I realized I'm trying to access the parameter the wrong way in my controller. It should not be a parameter to addAction, instead I should access it through the request object inside the function:
correct addAction in ShopController:
public function addAction()
{
$id = $this->_request->getParam('productid');
echo "the id: ".$id;
}
I also realized I can simplify my route setup quite a bit in this case:
[routes]
routes.shop.route = "shop/:action/:productid"
routes.shop.defaults.controller = shop
routes.shop.defaults.action = index