CakePHP - HABTM - sending data from multiple tables to a view - php

Scenario:
3 tables:
restaurants
cuisines
features
2 join tables:
cuisines_restaurants
features_restaurants
Question:
What is the best way to get data for a single restaurant from my controller to the view which includes not only the restaurant data, but also the cuisines and features that it has.
I have it working with this:
$restaurant = $this->Restaurant->find('all', array('conditions' => array('Restaurant.id' => $id)));
$this->set('restaurant', $restaurant);
And I'm calling it in the view like this:
echo "<span class='label'>Name:</span> " . $restaurant[0]['Restaurant']['name'] . "<br />";
echo "<span class='label'>Cuisine:</span> ";
$cuisineList = "";
foreach($restaurant[0]['Cuisine'] as $cuisine) {
$cuisineList .= $cuisine['name'] . ", ";
}
echo substr($cuisineList,0,-2) . "<br />";
(and repeat for Features)
But this seems overkill, since in all the Cake tutorials I see, the view method in the controller just has:
$this->set('restaurant', $this->Restaurant->read(null, $id));
Then they call it like this:
echo $restaurant['Restaurant']['name'];
...etc
Again - it IS working - I just want to know if there's a better way - the way I'm currently doing it seems sloppy compared to all the other slick things Cake does for me! :)

Your working code uses Model::find('all'), but when you want to retrieve just one Restaurant's data, you want to use Model::find('first'). I think you'll find if you change the first parameter of your call from 'all' to 'first', you'll get the data you want in the format you want.
Somewhat tangentially, there is quite literally no difference between the data returned by the two following calls:
$data = $this->Restaurant->find('first', array(
'conditions'=>array('Restaurant.id'=>$id)
));
or
$data = $this->Restaurant->read(null,$id);
Model::read is essentially a wrapper for Model::find('first'), though it also sets the model's internal state a bit (setting the Model::id and Model::data properties before returning data retrieved with Model::find('first')).

Related

How to implement search form in codeigniter

I have asked this question before but i did not get the right answer. I have a table 'cv', i want to search for items in the database using two fields i.e. course and location, the two items are on the same table('cv'). I dont have an idea on how to implement the two searches.
The code below is for displaying search for course only and its working fine. Help me to use the two search criterions i.e.course and location or in other words how do i add the search for location input in my code.
Controller
function search_worker()
{
$data['query']=$this->kint_model->search_workers($this->input->post('search'));
$this->load->view('hire_display',$data);
}
Model
function search_workers($search)
{
return $query = $this->db->get_where('cv', array('course '=> $search))->result();
}
View
$data = array('name'=>'search', 'id'=>'search','value'=>'bcom');
echo form_input($data);
$data = array('name'=>'submit', 'id'=>'submit', 'value'=>'Search Item(s)');
echo form_submit($data);
Maybe you need a like clause in your query,
function search_workers($search){
//return $query = $this->db->get_where('cv', array('course '=> $search))->result();
return $this->db->like('course', $search)->like('location', $location)->get('cv')->result();
}
You should also get some basic SQL training.

Joomla render full article by id with "JModelLegacy getInstance article"

I'm stuck trying to get joomla full article to render in a tab. The tab is working. I just can´t render the article content. This is where I am now.
This is helper.php
public static function getArticle($articleId)
{
JModelLegacy::addIncludePath(JPATH_SITE.'/components/com_content/models', 'ContentModel');
$model = JModelLegacy::getInstance('Article', 'ContentModel', array('ignore_request' => true));
$article = $model->getItem((int) $articleId);
$fullarticle = $item->fulltext;
$itemsHtml = '<div>'. $fullarticle .'</div>';
return $itemsHtml;
}
And this is in default.php
...code...
else if ($list_of_tabs['use'][$i][0] == 'article'){
echo '<div class="tab-pane '.$active.'" id="'.$i.$rid.'">'.
modJpTabsHelper::getArticle($list_of_tabs['article'][$i], $params) .
'</div>';
}
...code...
If you need more info. Don't hesitate to ask.
What are you trying to achieve: to write your own Joomla! extension which displays articles in a tab or you just need to display your J! articles in a tab?
If it's a latter, then there are already some nice and free (as in a "free bear") add-ons written just for that.
You are trying to use the model part of an MVC as a thing to render.
You should use the MVC system - using a controller to gathering the model and the view, and then you can render the model with the attached view, via the controller.
So you use something like (I've not tested this - you will need to correct it).
$filter=array('id' => $i->query['id']);
$options=array('filter_fields' => $filter,'ignore_request' => true);
$ctl = new ContentModelController();
$view = $ctl->getView( 'Article');
$model = $ctl->getModel( 'Article','',$options);
you may need to set params from application, eg..
$model->setState('params', JApplication::getInstance('site')->getParams());
then continue
$view->setModel( $model, true );
$result = $view->display();
Make sure that you have JLoader::import'ed any classes/classpaths - j. tends to fail silently if they aren't found, which can be difficult to trace.
Sorry, it's only a partial solution - but hopefully it may put you on the right track.
Here was the problem:
$fullarticle = $item->fulltext;
Article object from model was in variable $article not $item:
$article = $model->getItem((int) $articleId);
So getting property fulltext from article object should be:
$fullarticle = $article->fulltext;

How to add functions to a MVC Joomla component to access data from a different table?

I have a custom joomla MVC component created by http://component-creator.com with 4 tables:
#__mycomponent_items 27 Fields
#__mycomponent_bids 12 Fields
#__mycomponent_journeys 9 Fields
#__mycomponent_users 8 Fields
I am trying to set the relationships between these tables, but in the absence of documentation and experience I am struggling.
The basic relationships between the tables need to allow USERS to make BIDS to deliver ITEMS.
So I have created fields for items like this:
#__mycomponent_items
id
created
updated
ordering
state
checked_out
checked_out_time
created_by
deliverydestination
itemtitle
status
requiredby
listprice
deliveredprice
commission
points_reward
accepted_bid
accepted_bidder
accepted_journey
And for bid like this:
#__mycomponent_bids
id
state
created_by
item_id
buyer
bid
created
updated
bid_status
bid_expires
journey
arrival_date
I am working in templates/mytemplate/html/com_mycomponent/item/default.php and trying to add to that view a list of the current bids on that item. To do that I assume I need to add a custom function to /components/com_mycomponent/models/item.php and the function I have created is follows:
function itemBids() {
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select item record matching the $orderID
$query
//->select('*')
->select($db->quoteName(array('id', 'created_by', 'created', 'bid', 'bid_status', 'arrival_date')))
->from($db->quoteName('#__mycomponent_bids'))
->where('item_id = item.id');
// Reset the query using our newly populated query object.
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$db->setQuery($query);
$itemBids = $db->loadObjectList();
//print_r($itemBids);
}
How do I then access the data in the view /mytemplate/html/com_mycomponent/item/default.php?
I have tried this and it returns nothing:
<ul>
<?php foreach ($itemBids as $itemBid) :?>
<?php $arrivalDate = $itemBid->arrival_date; ?>
<li><strong><?php echo $itemBid->created_by; ?></strong> <small>can deliver for</small> $<?php echo $itemBid->bid;?> <small>
<?php /*?><abbr class="timeago" title="<?php echo $itemBid->created; ?>"></abbr><?php */?>
in <strong><abbr class="timeago" title="<?php echo $arrivalDate; ?>"></abbr></strong></small><div class="uk-badge uk-float-right"><?php echo $itemBid->bid_status; ?></div></li>
<?php endforeach; ?>
</ul>
You wouldn't be putting it in your template like that. the template just holds the layouts that generate the html. Also you need to have a default layout in your views/myview/tmpl folder.
You don't seem to be returning anything from your itemBids() function. You would want to add return $itemBids; or possibly return $this->itemBids; depending on what you are doing elsewhere.
YOu want to get $this->itemBids in your view.html.php class so that it is then available to your layout. THen instead of referring to $itemBids you can refer to $this->itemBids in your loop in the layout.
Have you been through the Creating an MVC Cmponent tutorial? It would probably help you get a sense of how MVC works in Joomla.
OK , as far as I understand you have a method in yourmodel.php and you are trying to access it from the view I did notice that you are not returning any values in your method
return $db->loadObjectList();
let me just make it simple by the below code
//com_component/models/yourmodel.php
class componentModelYourmodel extends JModelLegacy
{
function yourMethod()
{
//code
return $value;
}
}
And then in view file
//com_component/views/yourview/tmpl/default.php
//get the model first
$model=$this->getModel();
//call the method
$items=$model->yourMethod();
//print
print_r($items);

Why does loading all stores for a website depend on what store is currently loaded?

In Magento, there are several ways of how all stores for one or more website can be loaded. You could either do a Mage::app()->getStores(true) or a Mage::app()->getWebsites() and then walk through all stores in the resulting collection. This has already been answered here. What I discovered recently is, that loading a store before calling one of the methods above, is affecting the result. Especially regarding the default store. Example:
Setup: 1 Website with 3 Stores (english, french, german, while german is the default store)
Mage::app()->getStore()->load(0); // load admin store (or any other)
foreach (Mage::app()->getStores(true) as $store) {
echo "\n" . $store->getId() . " - " . $store->getCode();
}
result is:
0 - admin
1 - english
3 - french
Mage::app()->getStore()->load(2); // load german store (default)
foreach (Mage::app()->getStores(true) as $store) {
echo "\n" . $store->getId() . " - " . $store->getCode();
}
result is:
0 - admin
1 - english
3 - french
2 - german
Even stranger things happen when I'm browsing through the website to get it's stores. The default store's values are replaced with the values of the currenly loaded store:
Mage::app()->getStore()->load(0); // load admin store
foreach (Mage::app()->getWebsites() as $website) {
foreach ($website->getStores() as $store) {
echo "\n".$store->getId() . ' - ' . $store->getCode();
}
}
result:
1 - english
3 - french
0 - admin
in case of Mage::app()->getStore()->load(1) the result is:
1 - english
3 - french
1 - english
The only proper way I could get all stores a website independent of the currently loaded store was like this:
Mage::app()->getStore()->load($anyStoreId); // load any store
/** #var $websites Mage_Core_Model_Resource_Website_Collection */
$websites = Mage::getResourceModel('core/website_collection');
foreach ($websites as $website) {
foreach ($website->getStores() as $store) {
echo "\n".$store->getId() . ' - ' . $store->getCode();
}
}
result is always:
1 - english
3 - french
2 - german
What is the reason for these results? Is this a bug in Magento or is this behaviour intended? And are there better ways of how to load a website's stores?
take a look at the method Mage_Core_Model_App::getStore().
It accepts a parameter called $id but if that is null the current store is returned:
if (!isset($id) || ''===$id || $id === true) {
$id = $this->_currentStore;
}
Now...calling ->load() on a model, modifies the current object.
So when you call Mage::app()->getStore()->load(0) it has the following effect:
You retrieve the current store
You load the store with id 0 (admin)
Since objects are passed by reference you end up having in Mage_Core_Model_App::_currentStore the admin store.
And since Mage_Core_Model_App is instantiated as a singleton in the rest of the script you will have the admin store as the current store.
Further more, at the end of the same method there are these lines:
$this->_stores[$store->getStoreId()] = $store;
$this->_stores[$store->getCode()] = $store;
This caches the results of getStore in a member variable so you won't have to load it an other time. And _stores is used when calling getStores().
Conclusion.: Calling Mage::getStore()->load() can do much harm to your script. Calling this on a frontend page may result in access to some admin methods (not controllers or actions though). To iterate through stores and website you the Mage::getResourceModel() approach.

Search a specific database field with CakePHP post method

I’m trying to implement a simple search into an application, but not sure of the best way to handle this. My database contains a Listings object which includes City field. I want to create a search form where the user inputs a city into a text field and gets all of the Listings for that city on the next page. I don’t want to perform a full-text search, just the query on that City field.
Also, on the results page, I’d like to store the query in POST and can’t figure out the best way to do this.
What is the best way to approach this in the controller?
Well your view would look something like this
$this->Form->Create('Listing', array('action'=>'search'));
$this->Form->input('city', array('default'=>$city));
$this->Form->end();
if (isset($listings)) {
//code to display listings
}
This view would create the correct form. And your controller needs to get that value
function search() {
$city = '';
if (!empty($this->data)) {
$city = $this->data['Listing']['city'];
$opts = array(
'conditions' => array('Listing.city' => $city)
);
$listings = $this->Listing->find('all', $opts);
$this->set('listings', $listings);
}
$this->set('city', $city); // so the keyword is saved. Can also get it via $this->data
}
This code should give you an idea on how to do this.
This is a great tutorial with a CakePHP search plugin tutorial. You can download the full working code as well from github (w/ MySQL dump).
View:
<?php echo $this->Form->create()
echo $this->Form->input('search');
?>
<input name="data[Product][word]" />
controller:
<?php
$result = $this->Product->find('all',array(
'conditions'=>array(
'OR'=>array(
array('name LIKE'=>'%'.$word.'%'),
array('description LIKE'=>'%'.$word.'%')))));
$this->set(compact('result'));
?>

Categories