kohana 3.2 ORM find_all() with relationships - php

I have 3 tables:
artists{id,name}
media{id,name,filename}
media_artists{artist_id,media_id}
I created the models with n-n relationships as described in the Kohana guide.
When I do in a controller:
$artist_view = new View('artists/profile');
$artist_id = $this->request->param('id');
$artist_view->artists = $artist_model->where('id', '=', $artist_id)->find();
$artist_view->media = $artist_model->media->find_all();
it works fine, and I can call the media entries related to this specific artist in my view.
Now I want to do a query where I get all the artists, with their related media, all in the same sql result, but I don't find the syntax.
This:
$artist_view->artists = $artist_model->order_by('name' , 'ASC')->find_all();
$artist_view->media = $artist_model->media->find_all();
doesn't work (doesn't throw an error but $artist_view->media is empty)
I've seen on some forums that something like this might work:
$artist_model->order_by('name' , 'ASC')->with('media')->find_all();
but it doesn't work for me.
In my view, at the end, I want to be able to do something like this:
foreach($artists as $a){
echo $a->name."<br />";
foreach($a->media as $m) echo $m->name."<br />";
echo "<br />";
}

If you have the relationhsip in both models defined as follows:
// In artist model.
protected $_has_many = array(
'media' => array('through' => 'media_artists'),
);
// In media model.
protected $_has_many = array(
'artists' => array('through' => 'media_artists'),
);
It should work using (EDIT!):
$artists = ORM::factory('artist')->find_all();
foreach ( $artists as $artist )
{
foreach ( $artist->media->find_all() as $m )
{
echo $m->name;
}
}
I had the same problem in one of my projects and this solution works for me (Kohana 3.2.0).

Related

How to retrieve data from database Phalcon php

I'm using tutorial-master https://docs.phalconphp.com/en/latest/reference/tutorial.html the Create step from CRUD is awesome, I can input data to database. But I don't understand how to generating data from table using query.
this code didn't work because I use $application = new Application($di); not micro.
// Retrieves all robots $app->get('/api/robots', function () use ($app) {
$phql = "SELECT * FROM Robots ORDER BY name";
$robots = $app->modelsManager->executeQuery($phql);
$data = array();
foreach ($robots as $robot) {
$data[] = array(
'id' => $robot->id,
'name' => $robot->name
);
}
echo json_encode($data);
});
I want to have
$query="SELECT * FROM ospos ORDER BY ospoId"; and output $data = array(); echo jsone_encode($data) and resulting same result as micro code.. please help Thank you.
UPDATE: your above query using models.
$robots = Robots::find([
'order' => 'name'
]);
Find the below mentioned link (PhalconPHP model docs)
https://docs.phalconphp.com/en/latest/reference/models.html
Hope this link have an answer for your issue.
I couldn't find any satisfying answer so i thought of commenting how i did this.
In a controller do the following:
use Phalcon\Mvc\Controller;
$this->aricleModel = new Articles();
class IndexController extends Controller
{
public function indexAction()
{
$articles = Articles::find();
if ($articles) {
foreach ($articles as $article) {
echo $article->title;
echo "<br>";
}
}
}
}
Assuming you already made the model. the key is this: $this->aricleModel = new Articles(); Without it foreach won't work.

'where' condition in has_many_through in kohana

I have two models Illness and Symptom:
Illness
class Model_Illness extends ORM {
//protected $_db_group = 'default2';
protected $_table_name = 'illnesses';
protected $_has_many = array(
'symptoms' => array(
'through' => 'symptoms_illnesses',
'foreign_key' => 'illness_id',
)
);
Symptom
class Model_Symptom extends ORM {
//protected $_db_group = 'default2';
protected $_table_name = 'symptoms';
protected $_has_many = array(
'illnesses' => array(
'through' => 'symptoms_illnesses',
'foreign_key' => 'symptom_id',
)
);
The logic is illness may have many symptoms and symptom may have many illnesses. So these two have middle table symptoms_illnesses which stores ids of interconnected illnesses and symptoms.
Finally my task: I have to make search of illnesses by symptoms. I send symptom ids in array, and then should get illnesses which only have these symptoms. I tried following function:
public function bySymp($symps){
$res = array();
$objs = ORM::factory('Illness')->join('symptoms_illnesses')
->on('symptoms_illnesses.illness_id', '=', 'illness.id');
foreach($symps as $s){
$objs = $objs->where('symptoms_illnesses.symptom_id', '=', $s);
}
foreach($objs->find_all() as $o){
$res[] = $o;
}
return $res;
}
It returns nothing, when I put more than one value in array. I also tried $objs = $this->where('symptom_id', 'IN', $symptom_ids); it works like 'OR' condition, but I have to output exactly such illnesses that have symtoms in array of symptoms id's.
I think you would need to do multiple joins, one for each sympton. But a quick look into the Kohana documentation shows, that it doesn't allow for aliases inside queries, so a constructing a WHERE clause is difficult/impossible.
The only way I see that this works out of the box would be first finding all illnesses and then checking via has() for the required symptons.
$res = array();
$objs = ORM::factory('Illness')->find_all();
foreach ($objs as $o) {
if ($o->has('symptom', $symps)) {
$res[] = $o;
}
}
return $res;
But I haven't worked with Kohana in some time and might be overlooking something.

cakephp pagination and thin controller

i am developing with cakephp (2.4.7) and i have problems with organizing my controllers and models to use pagination.
So far i put the most logic into the models (thin controller, big model). There i returned the results to the controller where i set the variables to display it on the view.
But now i want to use pagination. This break my concept because i can not use pagination inside the models.
Whats the best solution to solve this problem? I do not want to reorganzie my whole structure, because i need pagination in a lot of different actions and models.
For example:
Controller Users, action friends
public function friends($userid = null, $slug = null) {
$this->layout = 'userprofile';
$this->User->id = $userid;
if (!$this->User->exists()) {
throw new NotFoundException(__('Invalid User'));
}
$this->set('friends', $this->User->getFriendsFrom($userid));
}
User Model, function getFriendsFrom($user_from).. i need this method in different actions.
public function getFriendsFrom($user_from) {
$idToFind = $user_from;
$data = $this->FriendFrom->find('all',
array(
'conditions'=>array(
'OR'=> array(
array('user_to'=> $idToFind),
array('user_from'=> $idToFind)
),
'AND' => array(
'friendship_status' => 1
)
),
'contain' => array('UserFrom.Picture', 'UserTo.Picture')
)
);
$friendslist = array();
foreach ($data as $i) {
if ($i['FriendFrom']['user_from'] == $idToFind){
$friendslist[] = $i['UserTo'];
}
elseif ($i['FriendFrom']['user_to'] == $idToFind){
$friendslist[] = $i['UserFrom'];
}
}
return $friendslist;
}
Whats the best way to design this concept to use pagination?
Thanks
in Controller Users use cakephp Paginator
var $helpers = array('Paginator');
Now you call the following method
function index() {
$result = array(
'recursive' => -1,
'conditions' => array(...),
'contain' => array(...),
'limit' => '2'
);
// you can write the above code in your model
$this->paginate = $result;
$users = $this->paginate('User');
// Re-arrage $users
$this->set(compact('users'));
}
If any problem, let me know.

Cakephp not rendering views

I have a controller, that doesn't render a view (the file is present). It just simply shows a blank page.
Also it happens only on staging server - two other dev environments work fine.
Here's the code:
function category($catId = null)
{
if (!isset($catId) || empty($catId)) {
$this->data['category'] = 'all';
$this->data['categories'] = $this->ShopCat->find('all',array('order'=>array('ShopCat.title ASC')));
$this->paginate = array(
'limit' => 9,
'order' => array('ShopProd.featured DESC','ShopProd.title ASC')
);
$this->data['products'] = $this->paginate('ShopProd');
} else {
$catId = (int) $catId;
$this->ShopCat->id = $catId;
if (!$this->ShopCat->exists($catId)) $this->cakeError('error404');
$this->data['category'] = $this->ShopCat->find('first', array('ShopCat.id' => $catId));
$this->data['categories'] = $this->ShopCat->find('all',array('order'=>array('ShopCat.title ASC')));
$this->paginate = array(
'conditions' => array('ShopProd.shop_cat_id' => $catId),
'limit' => 9
);
$this->data['products'] = $this->paginate('ShopProd');
}
}
Why isn't this working? Cause I have no ideas ...
UPDATE : the whole controller code runs ok, it just simply doesn't render anything. In other controller methods - all fine, works perfectly.
UPDATE : issue resolved, thanks to everyone :) it was an error in a view file.
Your $catId will always exist. You have declared in the function.
Maybe is more useful updated your first if to
if (empty($catId)) {...}
Do you have imported the another model in your controller?
Like: $uses = array('ShopCat', 'ShopProd');
or use App::import('Model', 'ShopCat') before $this->find
Figured it out - there was an error in a view file.

Loading corresponding entities while loading a collection

Currenty I'm working on a webshop using an auction module. This auction module has its own set of entities representing an auction and their bids. The main entity is the ProductAuction model. This model has an relation to the Catalog_Product model of Magento.
Everywhere the collection is loaded the products have to be loaded after the collection of ProductAuctions has been loaded.
Now I have to write some exotic queries to load a specific sets of auctions in combination with category and search queries. Now I first have to load a collection of products belonging to the given category and search query, then load the active auctions belonging to the set of corresponding products.
In some scenarios I can't reuse the set of loaded products and then have to execute another query to load the products corresponding the auctions.
Worst case I'll have to execute three big queries and process the resultsets which should be possible in one query.
Is it possible in Magento to load relating entities within a collection, just like any decent ORM would do with One-2-One, Many-2-One and other relations?
I haven't found any example of this, but I can't imagine this isn't possible in Magento.
Thanks for any help on this.
== EDIT ==
A bit of example code to show what I'm doing at the moment:
/**
* Build the correct query to load the product collection for
* either the search result page or the catalog overview page
*/
private function buildProductCollectionQuery() {
/**
* #var Mage_CatalogSearch_Model_Query
*/
$searchQuery = Mage::helper('catalogsearch')->getQuery();
$store_id = Mage::app()->getStore()->getId();
$productIds = Mage::helper('auction')->getProductAuctionIds($store_id);
$IDs = array();
$productIds = array();
$collection = Mage::getModel('auction/productauction')
->getCollection()
->addFieldToFilter(
'status', array('in' => array(4))
);
if (count($collection)) {
foreach ($collection as $item) {
$IDs[] = $item->getProductId();
}
}
$collection = Mage::getResourceModel('catalog/product_collection')
->addFieldToFilter('entity_id',array('in'=> $IDs ))
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addMinimalPrice()
->addTaxPercents()
->addStoreFilter();
if( $searchQuery != null ) {
$collection->addAttributeToFilter(array(
array('attribute' => 'name', 'like'=>'%' . $searchQuery->getQueryText() . '%'),
array('attribute' => 'description', 'like'=>'%' . $searchQuery->getQueryText() . '%')
)
);
// #TODO This should be done via the Request object, but the object doesn't see the cat parameter
if( isset($_GET['cat']) ) {
$collection->addCategoryFilter(Mage::getModel('catalog/category')->load($_GET['cat']) );
}
}
return $collection;
}
Managed to come up with a solution. I now use the following code to get all the information I need. Still I'm surprised it is so hard to create instances of relating objects like any normal ORM would do. But perhaps I am expecting too much of Magento..
Anyway, this is the code I use now:
/**
* Build the correct query to load the product collection for
* either the search result page or the catalog overview page
*/
private function buildProductCollectionQuery() {
/**
* #var Mage_CatalogSearch_Model_Query
*/
$searchQuery = Mage::helper('catalogsearch')->getQuery();
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addAttributeToSelect(array('product_id' => 'entity_id'))
->joinTable(array('productauction' => 'auction/productauction'), 'product_id=entity_id', array('start_time' => 'productauction.start_time','end_time' => 'productauction.end_time','entity_id' => 'productauction.productauction_id', 'product_id' => 'product_id'))
->joinTable(array('auction' => 'auction/auction'), 'product_id = entity_id', array('last_bid' => 'MAX(auction.price)'), 'auction.productauction_id = productauction.productauction_id', 'inner')
->addMinimalPrice()
->addTaxPercents()
->addStoreFilter()
->setPage((int) $this->getRequest()->getParam('p', 1), 1);
$currentCategory = Mage::registry('current_category');
if( $currentCategory != null ) {
$collection->addCategoryFilter($currentCategory);
}
if( $searchQuery != null ) {
$collection->addAttributeToFilter(array(
array('attribute' => 'name', 'like'=>'%' . $searchQuery->getQueryText() . '%'),
array('attribute' => 'description', 'like'=>'%' . $searchQuery->getQueryText() . '%')
)
);
// #TODO This should be done via the Request object, but the object doesn't see the cat parameter
if( isset($_GET['cat']) ) {
$collection->addCategoryFilter(Mage::getModel('catalog/category')->load($_GET['cat']) );
}
}
$collection->getSelect()->group('productauction.productauction_id');
return $collection;
}

Categories