PHP MVC in Joomla Component - php

Im working on a pre created joomla component which using the MVC Architecture, My problem like this:
In Models i have a .php file with database fetch function as
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.model' );
class class_name extends JModel
{
var $_data;
function getlast_year(){
$query = 'SELECT year FROM `table` ORDER BY year DESC LIMIT 0,1';
$this->_db->setQuery( $query );
return $this->_db->loadResult();
}
}
I added a new function to the same class file: (I have updated the table columns too in MVC /tables)
as:
function getAttendenceData()
{
$query="SELECT id,octSec,octNin,octSect,octSec,octTwent FROM `table`";
$this->_db->setQuery( $query );
//$this->_data = $this->_db->loadObjectList();
$this->_data = $this->_db->loadObject();
return $this->_db->loadObjectList();
}
but in view i cant still access the fetched data from the above new function but older functions are working property

This is not an actual answer but response to the comment.
First in your view.html.php file, you'll have to retrieve data from the model.
$attendance_data = & $this->get('AttendenceData');
This'll give you the object list as you are returning from your getAttendenceData() function.
Now assign it to a view variable (lets say data).
$this->assignRef('data', $attendance_data);
Now you can access this data in your view:
foreach($data as $r)
{
echo $r->id;
}

Isn't the problem that you are attempting to fetch the data twice?
With this line you retrieve it and store it locally in the class's _data variable.
$this->_data = $this->_db->loadObject();
With this line you attempt to retrieve the data again but you've already retrieved it (if there was only one result). You therefore are probably returning a false
return $this->_db->loadObjectList();
You should probably return $this->_data at the end of the function - assuming the original function you are copying was indeed functional.

Related

Pass variable from controller to view

In my controller, I can get the organization name but when I pass it to the view
there's an error. It said invalid argument supplied for foreach( ):
.
This is my codes.
Controller
public function index()
{
$user_id = $this->session->userdata('user_id');
$data['title'] = "User";
$getID['orgID'] = $this->userModel->getOrganizationID($user_id); // used my session user_id to
foreach ($getID['orgID'] as $orgID)
{
$org_id = $orgID->org_id;
$getName['myOrganization'] = $this->userModel->myOrganization($org_id);
foreach($getName['myOrganization'] as $orgName)
{
$name = $orgName->org_name;
$data['name'] = $name;
}
}
$this->load->view('xxxx/xxxx/xxxx',$data);
Model
public function getOrganizationID($user_id)
{
$this->db->select('org_id');
$this->db->from('organization_members');
$this->db->where('user_id', $user_id);
$query = $this->db->get();
return $query->result();
}
public function myOrganization($org_id)
{
$this->db->select('org_name');
$this->db->from('tblorganization');
$this->db->where('org_id', $org_id);
$query = $this->db->get();
return $query->result();
}
My output
First array is my result of $getID['orgID'] = $this->userModel->getOrganizationID($user_id); which I used my user_id session to get all the org_id of the user then
Second array is my result of $getName['myOrganization'] = $this->userModel->myOrganization($org_id); which I used my org_id(from my previous method) to get all the org_name of the user.
Is there going to be more then one result? Because if its only one result then you can use $query->row(); and eliminate the foreach completely.
Always check to make sure your database method worked AND that you actually got a returned value whenever you are making any database call. So i'll let you add the if condition in the database method but in short it should return FALSE if nothing came back. So thats the database method heres one way of doing it in your controller. Note this: $getID['orgID'] is very awkward. You are getting results back from the members table so call it members.
// check for the negative first - if no members came back
if( ! $members = $this->userModel->getOrganizationID($user_id) )
{
// if no results back leave this method
// pass the user id so you can echo it out in the error page
$this->showNoResultsFor($user_id) ;
}
else{
foreach ($members as $member)
{
$org_id = $member->org_id;
// etc etc etc
I'm not a codeigniter expert but looking at your code, I am wondering why you are setting:
$getID['orgID'] = $this->userModel->getOrganizationID($user_id);
First, you are setting an array $getID['orgID'] rather than just using something like $memberships = ...; I'm not sure why you are casting an array.
Secondly, you seem to be referencing a model class without instantiating it:
$this->userModel->getOrganizationID($user_id);
Perhaps codeigniter does some magic? $this refers to this instance and from the code you show, your model is likely in a separate class/file so I am unclear how $this->userModel is referenced in your method, unless you are instantiating it in your Controller's constructor?
From what I see it looks like you are getting the error because you are not supplying a valid object/array to your foreach. Perhaps start by testing you are actually getting a valid return from $this->userModel->getOrganizationID($user_id).

slim framework calling functions within functions

I don't know if you're supposed to refer to them as "functions" but...
My when my add_record function is called, I want to re-use another function I have made which gets a list of team names from the database;
public function add_record($data){
$teamnames = function get_teamnames;
print_r($teamnames);
exit;
/*
$this->db->query('INSERT INTO reports(`date`,refereename, refereeteam, hometeam, homecaptain, awayteam) VALUES (
"'.strtotime($data['date']).'",
"'.$data['refereename'].'",
"'.$data['refereeteam'].'",
"'.$data['hometeam'].'",
"'.$data['captainname'].'",
"'.$data['awayteam'].'"
)');
*/
}
And here is my get_teamnames function (from within the same file)
public function get_teamnames(){
//Get team data from database, place into resource.
$teamsData = $this->db->query('SELECT * FROM teamnames ORDER BY teamname ASC');
// Array which we will return to the Slim router
$teams = array();
// PLace all the teams from the mysql resource into the array
while ($row = $teamsData->fetch_object()) {
$teams[] = $row;
}
// Return the teams array
return $teams;
}
The reason I want the list of teamnames available in my add_record function, is so that I can do some validation on the $data and make sure that what's being submitted is only one of those team names stored in the database.
Assuming these functions are in the same class and you are using an object of the class, just do:
$teamnames = $this->get_teamnames();

Calling model function in view codeigniter

I am new to MVC, I am porting a project written in non-MVC style to MVC, but I am stuck on a problem where it is necessary to call Model function in View.
Scenario:
Table1 - Products:
contains product_id, product_name etc. and for each product there can be multiple versions.
Table2 - Versions:
contains version_id, version_name, ... , product_id etc.
Now in the View I am displaying products and under each product heading I have to display version list of that product, in non-MVC style it was pretty simple, I can use the following code snippet in View:
foreach ($product as $row)
{
echo $row['product_name'];
if ($main->getVersionList($vresult,$row["product_id"]))
{
foreach ($vresult as $vrow)
{
echo $vrow['version_name'];
}
}
}
Now, I can pass Product array from controller to view but what about each Version array which needs to be generated corresponding to each product?
Update:
This is my final working solution (used a map), in controller:
$this->load->model ( 'product_mod' );
$data ['products'] = $this->product_mod->getProductList ();
$data ['versions'] = array ();
foreach ( $data ['products'] as $product )
{
$data ['versions'] [$product['product_id']] = $this->product_mod->getVersionList ( $product['product_id'] );
}
MVC or not to MVC
The first thing I should note is that It is impossible to write classical MVC in PHP. In fact the MVC-like PHP frameworks such as CodeIgniter or Yii implements sort of MVP in which:
view is passive and unaware of model
presenter (controller) changes state of model, reads information and passes it to view
Credits to tereško
CodeIgniter Approach
However, particularly in CodeIgniter, you have 3 steps:
Create a Model to query through the database and return the data (as an array or object)
Create a Controller to load and fetch the result from the Model (a method of the Model), and pass the returned data to the view
Create a View and use PHP loops to echo the result out, build the HTML.
Getting all together
Considering the above approach, you need to fetch the result from the database in your Model:
application/models/product.php
class Product extends CI_Model
{
public function get_product($product_id)
{
$this->db->select('*')->from('products');
$this->db->where('product_id', $product_id);
$this->db->join('versions', 'versions.product_id = products.product_id');
$query=$this->db->get();
return $query->first_row('array');
}
}
Then fetch and pass the result within the Controller:
application/controllers/products.php
class Products extends CI_Controller
{
public function view($product_id)
{
$this->load->model('product');
// Fetch the result from the database
$data['product'] = $this->product->get_product($product_id);
// Pass the result to the view
$this->load->view('product_view', $data);
}
}
Finally, use the returned data in the view, to generate the list:
application/views/product_view.php
// Use $product to display the product.
print_r($product);
You should do mysql query in your model, for example products_model (don't forget to load it)
Example Query : This is just select * from products
public function All_Products()
{
$this->db->select('');
$result = $this->db->get('products')->result_array();
return $result;
}
So as I see , you are foreach guy like me, rather than using mass queries.
In your controller you could load $products my your model.
$products = $this->products_model->All_Products();
My solution is creating a new array then putting new values in it.Also you need to getVersionList function in your model.
$newArray = array ();
foreach ( $products as $values ) {
$version = $this->products_model->getVersionList($values['product_id']);
$tmp = array (
'product_id' => $values ['product_id'],
'product_name' => $values ['product_name'],
'version' => $version
);
array_push ( $newArray, $tmp );
}
So add your new array to $data you could have them in your view file.
$data ['products'] = $newArray;
Sorry I didnt figure out all your queries but I think its better to teach how to catch fish than giving a fish.
Using the below code you can call the model's method in the view file. It's worked for me and is so simple also.
$CI =& get_instance();
$CI->model_name->method_name();

Fetch data from database issue

i have one issue i make a component and i add data add component data table that i want to fetch that data in my site how to do and i have one other issue how to put query in view.html.php file in components i have code i add my code i have one error i add my error
500 - View class not found [class, file]: team_memberViewteam_member, C:\wamp\www\Joomla_2.5.8-Stable-Full_Package\components\com_team_member\views\team_member\view.html.php
this is my code please help me how to fetch data in database....
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HTML View class for the HelloWorld Component
*/
class HelloWorldViewHelloWorld extends JView
{
// Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select(array('id', 'member_name', 'member_pic', 'member_des','member_description'));
$query->from('#__gztqw_team_member_datadetails');
$query->where('profile_key LIKE \'custom.%\'');
$query->order('ordering ASC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects.
$results = $db->loadObjectList();
// Display the view
parent::display($tpl);
}
}
try simple way:-
$db = JFactory::getDbo();
$query = 'SELECT data FROM #__gztqw_team_member_datadetails WHERE profile_key LIKE "custom.%" order by ASC';
$db->setQuery($query);
$results = $db->loadObjectList();
also you have not returened any value in function and where you have display it the best way to show data in view use controllers function and assign result value to display in view
you need to read http://docs.joomla.org/Developing_a_Model-View-Controller_%28MVC%29_Component_for_Joomla!2.5
First of all, the class in your view is called HelloWorldViewHelloWorld, it should be called Team_memberViewTeam_member, this is what is causing your error.
Secondly, You should ideally put your database query into your model, however it will still work if you put it in your view. I have given you an example of how to make it work with the query in the view.
I have created a protected variable called $items, and assigned the results from the database to the variable.
In your template, you would then access the data from the database using
foreach($this->items as $item):
echo $item->id;
endforeach();
In your view you should have
class Team_memberViewTeam_member extends JView
{
protected $items;
// Overwriting JView display method
public function display($tpl = null)
{
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select(array('id', 'member_name', 'member_pic','member_des','member_description'));
$query->from('#__gztqw_team_member_datadetails');
$query->where('profile_key LIKE \'custom.%\'');
$query->order('ordering ASC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects.
$this->items = $db->loadObjectList();
parent::display($tpl);
}
}

Magento Controller shows all the rows from table

As I am required to pirnt the ratings of products in JSON format, i have made a module with controller and rating.php file in model folder. We I run the controller it shows all the data from that table, But I required only a single row. So through the url i am passing a parameter, but it wont works. I am attaching my indexcontroller.php here. suggest me upon this.
<?php
class Modulename_CustomRating_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction ()
{
$arrParams = $this->getRequest()->getParams();
var_dump($arrParams);
$collection = Mage::getModel('Modulename_CustomRating_Model_CustomRating')->getCollection();
}
print_r (json_encode($collection ->getData()));
}
}
?>
As I am passing url as:localhost/magento/customrating?vote_id=1 , it is taking the parameter to it but returns whole table's data. I know this is due to getData(); but how to make to get the required row?
You have to use setEntityPkFilter method. Check Mage_Rating_Model_Resource_Rating_Option_Vote_Collection class for other methods.
$product_id = $this->getRequest()->getParam('product_id'); // or 'vote_id'
$collection = Mage::getModel('Modulename_CustomRating_Model_CustomRating')
->getResourceCollection()
->setEntityPkFilter($product_id);
If you want only 1 column you can try some Zend stuff because you can't use addAttributeToSelect. getSelect() returns Zend like query:
$adapter = $this->getConnection(); // $this->getConnection();
$collection->getSelect()
->reset(Zend_Db_Select::COLUMNS) // remove all columns
->columns('attribute_name'); // add only needed one
$result = $adapter->fetchAll($select);
Not sure whether this would work. It's not tested, just an idea.

Categories