Zend framework - access controller or model from the view - zend-framework

I need to give the front-end designer the ability to choose whether or not to display a single xml feed or an mash-up, from the view.phtml file
This means I need to be able to call a method from the controller or model which then returns a variable to the view containing the requested feed(s).
So how do I access methods of the controller or model from the view?

you don't call controller methods in view , but you can create an instance of model (for read only purposes) inside view and then call its public methods .eg
Foo.phtml
<?php $feedsTb = new Default_Model_Feeds() ?>
<?php $allFeeds = $feedsTb->fetchAll(); ?>

I don't know if i got your problem right, but this is something i'd probably do in a way like
Controller:
if($this->_getParam('single')) {
$this->view->data = $model->getFeedSingleData();
$this->render('single_feed.phtml');
} else { //mashup
$this->view->data = $model->getMashUpData();
$this-render('mashup_feed.phtml');
}
Though admittedly an example like this is better off with two different actions (singleAction() and mashupAction())
But i really don't know if i got your problem figured out at all :S You may explain it further

Related

call Zend framework view helper from within own view helper

Zend Framework 1.12
I have written my own view helper and need to call a Zend view helper from within it.
In my view file, I can call
$this->formSelect (...) to get a select dropdown
however in my own view helper file
$this->view->formSelect (...)
causes an error
Call to undefined method Zend_View_Helper_MilestoneList::formSelect()
How can I access Zend Framework view helpers from within there?
It is very simple to call another View Helper.
Your view helper extends must be extend Zend_View_Helper_Abstract, so that it has access to the $view. Then you may simply call helpers as you would from a view, i.e.
$this->view->generalFunctions()->progressMeter();
For example you can access it in to your view:
<?php
class Zend_View_Helper_FormVars extends Zend_View_Helper_Abstract {
/* ... */
public function mkCategoryCodeSelectGroup($codeTypeArr=array(),
$codesArr=array()) {
$html='';
$html. $this->view->generalFunctions()->progressMeter();
return $html;
}
}
Please set class name as per your need. and just try it.
let me know if i can help you
I found that
$selectFormHelper = $this->view->getHelper('FormSelect');
$selectFormHelper->formSelect(...)
works, but
$this->view->formSelect(...)
does not.
I'm not sure why that is, but happy to live with it for now.

How do I avoid repetition when passing variables from the Controller/Action to the Layout

I am currently working on a project developed using Zend Framework, based on the structure of my web page design I have reached a point where I have to pass a small number of variables to my layout from each Controller/Action. These variables are:
<?php Zend_Layout::getMvcInstance()->assign('pageId', 'page1'); ?>
<?php Zend_Layout::getMvcInstance()->assign('headerType', '<header id="index">'); ?>
The reason for passing this information is firstly, I pass the page id as the multi column layout may change depending on the content being displayed, thus the page id within the body tag links the appropriate CSS to how the page should be displayed. Secondly I display a promotional jQuery slider only on the index page, but I need the flexibility to have it displayed on potentially multiple pages in case the wind changes and the client changes their mind.
My actual question: Is there a more appropriate method of passing this information to the Layout that I am overlooking?
I am not really questioning whether the information has to be sent, rather is there some Zend Framework feature that I have, in my haste, overlooked which would reduce the amount of repetitive redundant code which may very well be repeated in multiple Actions within the same controller?
You could turn that logic into an action helper than you can call from your controllers in a more direct way. You could also make a view helper to accomplish the same thing but view helpers usually generate data for the view rather than set properties.
// library/PageId.php
class Lib_PageId extends Zend_Controller_Action_Helper_Abstract
{
public function direct($title, $pageId, $headerType)
{
$view = $this->getActionController()->view;
$view->headTitle()->append($title);
$view->pageId = $pageId;
$view->headerType = $headerType;
}
}
In your controller actions you can now do this:
$this->_helper->PageId('Homepage', 'page1', 'index');
// now pageId and headerType are available in the view and
// Homepage has been appended to the title
You will also need to register the helper path in your Bootstrap like this:
protected function _initActionHelpers()
{
Zend_Controller_Action_HelperBroker::addPrefix('Lib');
}
Doing it like that can reduce the amount of repetitive code and remove needing to assign the values from the view. You can do it in the controller very quickly. You can also have default values in the case that the helper hasn't been called.
You shoudn't really be passing anything from the view to the layout, for a start the view should be included IN the layout, not the other way around.
So, setting your page title should be done using similar code to what you have, but inside the controller action being called:
$this->view->headTitle()->append('Homepage');
And the other two issues - you need to rethink as I stated to begin with. Maybe you're misunderstanding the layout/view principle? If you include the different views per action, then you simply change the div id when needed, and include the header for your banner only in the index.phtml file.

How does one create a SugarCRM View that combines 2 Detail Views

I would like to extend the Contact Detail View so that a Detail View of the associated account appears on the same view.
MY instinct is to override the display function for the Contacts Detail View and from there create an instance of the Accounts Detail and attach it's display output.
But I don't know if there is a standard way of pulling this of.
I learned that in the up coming version (6.3), there will be a way of generating computed fields that have access to the fields of a related module.
If this is the case, then one option will be to create computed fields that reference the Account fields and then add a panel to Contact DetailView with the referenced Account fields.
Though, my original hunch proved to be doable as well and not as hacky as I had assumed at first:
<?php
require_once('include/MVC/View/views/view.detail.php');
class ContactsViewDetail extends ViewDetail {
function ContactsViewDetail() {
parent::ViewDetail();
}
function preDisplay(){
parent::preDisplay();
// Configuration to display All account info
$this->dv2 = new DetailView2();
$this->dv2->ss =& $this->dv->ss;
$this->bean2 = new Account();
$this->bean2->retrieve($this->bean->account_id);
$accountMetadataFile = 'custom/modules/Accounts/metadata/detailviewdefs.php';
$accountTemplate = 'custom/modules/Accounts/tpls/AccountsDetailView.tpl';
$this->dv2->setup('Accounts', $this->bean2, $accountMetadataFile, $accountTemplate);
}
function display(){
parent::display();
// Display Accounts information.
$this->dv2->process();
echo $this->dv2->display();
}
}
?>
In summary
Override the detail view.
Add a new display to the current View.
Add a new bean (module) to the View.
Process the display with the new bean.
Echo the display.
Another easier option may be just add an iframe field, which loads the detailview on the account inside of it. Not as pretty, but lots less hacking as well.

passing values from model to view in CI

I have this library in CI that retrieves my latest twitter updates. It has a function that sends my latest updates as objects to my controller.
I would like to show these twitter updates on the footer of my page, so they're visible at all times.
Now my question is how I call these directly from a view? I know this is not a good practice in MVC but I don't see how else I could do this.
My controller currently takes care of all my different pages (it's a small website) and I don't think it's very good practice to call my twitter class at the end of every page-function in the controller and then send it through to the views.
Typycally I do this in my controller:
<?php
function index(){
$data['page'] = 'home';
//i don't want to call my twitter class here every single time I write a new page. (DRY?!)
$this->load->view('template', $data);
}
?>
And it loads the "template" view that looks like this:
<?php
$this->load->view('header');
$this->load->view('pages/'.$page);
$this->load->view('footer');
?>
So any suggestions how I should do this?
I have a helper library that takes a page Partial and wraps it in the master theme. You can use the optional parameter on your load->view to render to a string.
Then when you render your master page, you can load the twitter updates, and display them. Although, I highly suggest caching your twitter response for 5 minutes at least, will save you a LOT of overhead.
Example:
// Controller somwhere:
$content = $this->load->view('pages/'.$page, array(), true);
$this->myLibrary->masterPage($content);
// Your library:
function masterPage($content)
{
$twitterData = $this->twitter->loadStuff(); // whatever your function is
$twitter = $this->load->view('twitter_bar', array('data' => $twitterData), true);
$this->load->view('master', array('content' => $content, 'twitter' => $twitter);
}
An alternative approach is to use a base controller. All my controllers extend my custom base controller which holds things I need on every page, for example an object containing the current user.

dojo.data is undefined Flitering select

I am having a few problems with Dojo Filtering Selects when using the Zend Framework Forms and need some help to find out what I have missed as this is driving me mad.
I am currently getting this errors in firebug:
dojo.data is undefined
dojo.data.ItemFileReadStore is not a constructor
Below is the code that I am using to create the filter select and provide the json data to the calling controller.
Zend_Form Element (Dojo Enabled)
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setStoreId('industrystore')
->setStoreType('dojo.data.ItemFileReadStore')
->setStoreParams(array('url' => $baseUrl.'/dojo/industry'))
->setAttrib("searchAttr", "title")
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
Dojo Controller
public function industryAction(){
$db = Zend_Db::factory($this->config->database);
$result = $db->fetchAll("SELECT * FROM industries");
$data = new Zend_Dojo_Data('industryid', $result);
$this->_helper->autoCompleteDojo($data);
$db->closeConnection();
}
The annoying thing is all my other Dojo elements on this form and other forms work well it is just whenever I do Filtering Selects that I hit these problems, and this problem causes all the other elements in a form to fail too.
Thanks in advance.
The problem is actually with how Zend Framework initializes the dijits and data stores before the toolkit is fully loaded, in this case specifically the methods assigning the store to the dijit. I ran into this issue as well and found the best way to work around the issues was to either pass the data store from the controller to a JavaScript variable defined in the view or do what your did with a specific autocomplete action. Based on your example I would make the following changes.
In your form I would simplify the element:
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
In your view you want to connect the store to your dijit and make sure that you have loaded the dojo.data.ItemFileReadStore module:
<?php $this->dojo()->onLoadCaptureStart()?>
function(){
dijit.byId('industry').store = new dojo.data.ItemFileReadStore({ url: '/controller/industry' });
}
<?php
$this->dojo()->onLoadCaptureEnd();
$this->dojo()->requireModule('dojo.data.ItemFileReadStore');
?>
As I mentioned I ran into a similar issue which I answered here . Another issue I discovered is that the data store does not like dealing with labels declared anything other than "name" for the label declaration in the Zend_Dojo_Data.