Multiple Query in one model in joomla 2.5 - php

Can I do 2 separate queries in a model in joomla 2.5 ?
If it is possible, how do you do this?
This is my model:
<?php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.modellist' );
class AnagraficheModelServiziassociatiaggiuntivi extends JModelList
{
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array('id_servizi_aggiuntivi', 'id_persona', 'id_servizio', 'nome_servizio', 'cod_servizio', 'id_tipologia_socio', 'nome_servizio');
}
parent::__construct($config);
}
function getListQuery()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('id_servizi_aggiuntivi, id_persona , id_servizio , nome_servizio');
$query->from('#__servizi_aggiuntivi as serviziaggiuntivi, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->loadObjectList();
//$db->setQuery($query);
$query = $db->getQuery(true);
$query->select('id_tipologia_socio, id_servizio as cod_servizio, nome_servizio');
$query->from('#__associazione_servizi as serviziassociati, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->loadObjectList();
return $query;
}
protected function populateState($ordering = null, $direction = null)
{
// Load the filter state.
$search = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search');
$this->setState('filter.search', $search);
// List state information.
parent::populateState($ordering, $direction);
}
}
?>
This doesn't work, but if I delete the second query it works great!
In my opinion, the problem is in the function getListQuery(). In this function I want insert 2 queries not 1 query! Is it possible?

The short answer is no. getListQuery should return a query. You can't get it to return two queries.
Instead, you likely want to override the getItems function to process the items after the first query runs. You can either adjust or add items using something like the following:
public function getItems() {
// load items from the parent getItems function, which will call getListQuery to handle your first query.
//It only adds items if the first query works.
if ($items = parent::getItems()) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('id_tipologia_socio, id_servizio as cod_servizio, nome_servizio');
$query->from('#__associazione_servizi as serviziassociati, #__elenco_servizi');
$query->where('cod_servizio=id_servizio');
$result1 = $db->setQuery($query)->loadObjectList();
// this is a simple way to merge the objects. You could do other processing (loops, etc) to meld the information together
$items = (object) array_merge((array) $items, (array) $restult1);
}
return $items;
}

Related

PHP/Codeigniter Dry Principle on Model functions

Let's say i'm making a web application for a online story sharing site.
We have tables: genre,tags,content_warning with only 2 columns as id and name. for example: genre = 1 - romance, 2 - action, etc.
I use the above tables to control/define each genre/tags/contentwarnings. so whenever a user publishes/uploads their own story they just cant input random tags/genre/contentwarnings.
So i'll have these functions in my story_model:
public function get_genre(){
$genre = array();
$query = $this->db->get('genre');
foreach($query->result() as $row){
$genre[$row->genre_id] = $row->genre_name;
}
return $genre;
}
public function get_tags(){
$tags = array();
$query = $this->db->get('tag');
foreach($query->result() as $row){
$tags[$row->tag_id] = $row->tag_name;
}
return $tags;
}
public function get_content_warnings(){
$content_warning = array();
$query = $this->db->get('content_warning');
foreach($query->result() as $row){
$content_warnings[$row->content_warning_id] = $row->content_warning_name;
}
return $content_warning;
}
Am i correct to say that i am repeating myself in the above 3 functions? so i would write a single code like:
public function sample_get($table){
$data = array();
$query = $this->db->get($table);
foreach($query->result_array() as $row){
$data[$row[$table.'_id']] = $row[$table.'_name'];
}
return $data;
}
to access the above function in my controller i would pass 'genre' or 'tag' or 'content_warning' as the parameter.
How would i name my above function then? the 3 separate functions are easy to name as they are very direct to the point and you know what the function does by reading its name.
combining all 3 function into one makes it harder to name the function in a direct way. I like to name my function as direct as possible so its easy for me to follow. as in they're more readable.
Account_model:
public function get_userid($username){
$this->db->select('user_id');
$this->db->from('user');
$this->db->where('username', $username);
$query = $this->db->get();
foreach($query->result() as $row){
$user_id = $row->user_id;
}
return $user_id;
}
story_model:
public function get_stories($user_id){
$stories = array();
$this->db->select('story_id, story_name');
$this->db->from('story');
$this->db->where('user_id', $user_id);//author
$query = $this->db->get();
foreach($query->result() as $row){
$stories[$row->story_id] = $row->story_name;
}
return $stories;
}
would the above two function warrant a dry-ification?
Or let's change the second function to only get the story_id which would coincide with the account_model function to get user_id. would they then be needed to dry?
but i get confused as to when do i decide to dry my functions? since i'll use alot of get function to retrieve data should i then just opt for a single get function?
If you want to use your common, abstract function, but keep well-named public functions, you can take the following approach:
/**
* Use the common function internally, but do not expose it publicly
*/
private function sample_get($table){
$data = array();
$query = $this->db->get($table);
foreach($query->result_array() as $row){
$data[$row[$table.'_id']] = $row[$table.'_name'];
}
return $data;
}
/**
* Use well-named functions that are exposed to be used publicly
*/
public function get_content_warnings(){
return $this->sample_get('content_warning');
}
This makes it possible to structure your class internally (through using the keyword private), but maintain a good interface to be used by other classes (through using public).

Accessing class properties in PHP OOP

I am new in PHP OOP and was wondering if someone could help me with this.
I have a basic class with one method which returns data from database. Currently I am calling the method which displays everything inside the function.
Here is my class Definition:
class Products{
//properties
public $familyName = "";
public $familyProduct = "";
//Methods
public function getFamily($catId){
global $conn;
$sql = "SELECT * FROM product_family WHERE catID = '$catId'";
$result = $conn->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
echo "<li>".$row['familyName']."</li>";
echo "<li>".$row['familyProduct']."</li>";
}
}
}
}
Here is how I call the method:
$Products = new Products;
$Products->getFamily( 4 );
This works however, how can I assign each data coming from database ( ex familyName, familyProduct ) into variables inside class implementation and then access them individually where ever I need to. Something like this:
$Products = new Products;
$Products->familyName;
$Products->familyProduct;
I have empty properties but I am not sure how can I assign values to them coming from the loop and then return them each.
Thanks,
There are view things I would change in your Code.
Don't make Properties public use use Getters and Setters.
This will protect you Object from being used the wrong way e.g. now you can't change the familyName from outside: $products->familyName = "some value" because this would make the data of the object corrupt.
global $conn; is a no go in OOP use the construct of the Object,
in your case $products = new Products($conn);
Now you can set a Cat ID $products->setCatId(4); and read the result
$familyName = $products->getFamilyName(); or $familyProduct = $products->getFamilyProduct();
If you have more than one result you will get an array, if catId will always result one row you can delete this part. If you learn more about OOP you will find out that the hole SQL stuff can be done with a separate Object, but this is off Topic.
class Products
{
// Properties
protected $conn;
protected $catId;
protected $familyName;
protected $familyProduct;
public function __construct($conn)
{
$this->conn = $conn;
}
// set Cat ID and get date
public function setCatId($catId)
{
$this->catId = (int) $catId;
$this->getDate();
}
public function getCatId()
{
return $this->catId;
}
// get Family Name
public function getFamilyName()
{
return $this->familyName;
}
// get Family Product
public function getFamilyProduct()
{
return $this->familyProduct;
}
// get date
protected function getDate()
{
$sql = "SELECT * FROM product_family WHERE catID = '$this->catId'";
$result = $this->conn->query($sql);
// Default if no result
$this->familyName = null;
$this->familyProduct = null;
// if one Result
if ($result->num_rows == 1)
{
$row = $result->fetch_assoc();
$this->familyName = $row['familyName'];
$this->familyProduct = $row['familyProduct'];
}
if ($result->num_rows > 1)
{
$this->familyName = [];
$this->familyProduct = [];
while ($row = $result->fetch_assoc())
{
$this->familyName[] = $row['familyName'];
$this->familyProduct[] = $row['familyProduct'];
}
}
}
}

how to free codeigniter results while calling the same model twice

I have a situation, I have written a base model in codeigniter, all models extend from it, the base model has a function
public function load_all_by_keys($array, $limit = 0, $offset = 0) {
if ($limit) {
$query = $this->database->get_where($this::DB_TABLE, $array, $limit, $offset);
} else {
$query = $this->database->get_where($this::DB_TABLE, $array);
}
$ret_val = array();
$class = get_class($this);
foreach ($query->result() as $row) {
$model = new $class;
$model->populate($row);
$ret_val[$row->{$this::DB_TABLE_PK}] = $model;
}
return $ret_val;
}
in this function I am able to get lets say for instance, schools which are of category Abet
$abet = new School_Model();
// this query will get all schools with by column category whose value is Abet, thats fine
$abetSchools = $abet-?load_all_by_keys(array('category'=>'Abet'));
$primary = new School_Model();
// This second query fails with the error Fatal error: Call to a member function result() on a non-object
$primarySchools = $primary-?load_all_by_keys(array('category'=>'Primary'))
Can someone help
$this->db->flush_cache()
This function deletes all items from the Active Record cache (Reference http://ellislab.com/codeigniter/user-guide/database/active_record.html#caching)

return an array of objects

want from a method return an array of objects, what is the best way
retrieving data from the db and then populate a list of objects to be returned.
<?php
class DataObject{
public function GetObjetList(){
// Connect to the database server
$dbh = new PDO("mysql:host=localhost;dbname=bookdb", "webuser", "secret");
// Execute the query return 1200 register
$stmt = $dbh->query('SELECT sku, title FROM products ORDER BY title');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$sku = $row['sku'];
$title = $row['title'];
return something?? --> how to??
}
}
?>
regards!
PDO already has a fetch mode that returns objects.
Change your code to this:
while ($row = $stmt->fetch(PDO::FETCH_OBJ)) {
class DataObject
{
public function __construct($pdo)
{
$this->db = $pdo;
}
public function GetObjetList()
{
$sql = 'SELECT sku, title FROM products ORDER BY title';
return $this->db->query($sql)->fetchAll(PDO::FETCH_OBJ);
}
}
Put the return after the while, not inside, use FETCH_OBJ and an array:
$rows = array();
$rows = $stmt->fetchAll(PDO::FETCH_OBJ);
return $rows;

PHP OOP query is not executing

I am using PHP with OOP to select rows from the database (MySQL).
When I execute the query, it returns an empty row.
Here is the classe I am using:
<?php
class EmploiManager
{
private $_db;
public function __construct($db)
{
$this->setDb($db);
}
public function category($category)
{
$q = $this->_db->prepare('SELECT * FROM DemandeEmploi WHERE category = :category');
$q->execute(array('category' =>$category));
$donnees = $q->fetch(PDO::FETCH_ASSOC);
return new Emploi($donnees);
}
public function setDb(PDO $db)
{
$this->_db = $db;
}
}
$type = $_GET['category'];
$manager = new EmploiManager($db);
$row = $manager->category($type);
foreach ($row as $demandeE)
{
?>
<div class="list"><h4><? echo $demandeE->title();?></h4> </div>
<?php
}
?>
Can any one tell me what's wrong with that code?
Thanks!
It's my bad, I didn't use a loop to select all the rows.
I corrected the code and it works fine now, here is what it looks like:
public function category($category)
{
$datas = array();
$q = $this->_db->prepare('SELECT * FROM DemandeEmploi WHERE category = :category');
$q->execute(array('category' =>$category));
while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
{
$datas[] = new Emploi($donnees);
}
return $datas;
}
$q->fetch() just returns one row of the results. If you want all the results, you must use $q->fetchAll().
Since you specified PDO::FETCH_ASSOC, the elements of $row will be associative arrays, not objects; aren't you getting errors saying that you're trying to call a method on a non-object? So $demandeE->id() should be $demandeE['id'], and $demandeE->title() should be $demandeE['title'].
Alternatively, you could specify PDO::FETCH_OBJ. Then, the values will be properties, not methods, so it should be $demandeE->id and $demandeE->title (no parentheses).

Categories