Welcome Guest, Not a member yet? Register   Sign In
Get image url from model good practice?
#1

(This post was last modified: 11-06-2015, 07:42 AM by sebastianvirlan.)

Is this method a good practice?

Controller:

PHP Code:
$produse $this->produse->entries_by_limit((($page-1) * $config_pagina['per_page']),
 
$config_pagina['per_page'], $order_by'270'); 

Model:

PHP Code:
   function entries_by_limit($start$limit$order_by "order by id_produs asc"$rez) {
 
       $this->db->select('a.*');
 
       $this->db->select('b.nume_imagine'false);
 
       $this->db->from("$this->_table a");
 
       $this->db->join('imagini_produse b'"b.$this->_primary_key = a.id_produs""left");
 
       $this->db->limit($limit$start);
 
       $this->db->order_by($order_by);
 
       $result $this->db->get();

 
       foreach($result->result() as $single) {

 
        if($single->nume_imagine):
 
        $single->nume_imagine base_url('assets/uploads/'.$single->id_produs.'/'.$this->parse_image($single->nume_imagine$rez));
 
           else:
 
               $single->nume_imagine base_url('assets/images/no-product-image-available.png');
 
           endif;
 
       }

 
       return $result->result();
 
   }


 
   function parse_image($image_name$rez){
 
       $image explode('.'$image_name);
 
       return $image[0].'_'.$rez.'.'.$image[1];

 
   


and view

PHP Code:
<img class="primary-image" src="<?= $produs->nume_imagine ?>" alt=""


Should I use any helper or is ok like this?
Reply
#2

(This post was last modified: 11-10-2015, 01:42 AM by sebastianvirlan.)

I think a good start would be OOP, so I started:

PHP Code:
class Product
{

    private 
$_product;
    private 
$_resolution;

    public function 
__construct($product$resolution){

        
$this->_product $product;
        
$this->_resolution $resolution;
    }

    public function 
products() {

        foreach(
$this->_product as $product){
            
$product->nume_imagine $this->parse_image_name($product);
        }

        return 
$this->_product;

    }


    public function 
product() {

        
$this->_product->nume_imagine $this->parse_image_name($this->_product);

        return 
$this->_product;

    }


    private function 
parse_image_name($product)
    {
        if(
$product->nume_imagine):
            return 
base_url('assets/uploads/'.$product->id_produs.'/'.$this->image_resolution($product->nume_imagine$this->_resolution));
        else:
            return 
base_url('assets/images/no-product-image-available.png');
        endif;
    }

    private function 
image_resolution($image_name$resolution) {

        
$image explode('.'$image_name);
        return 
$image[0].'_'.$resolution.'.'.$image[1];
    }


The problem is I dont't know where to call and how to call. In model? In controller?
Reply
#3

In the world of MVC each request is routed to a Controller. You could ignore the M and V completely and do everything in your controller. But you will quickly see that this means duplicating a lot of code. So you start to use Models for Database communication. In your models you perform some logic to the DB results and return it to your controller. Again you will start to notice code duplication. So you start using helpers for common functions and libraries for more complex data handling. And thus you may start to use a business layer for your models.

I would say your Product class is a library and you pass a data package to this class. So how you call this could be
1. Controller --> request data from your model and return to Controller
2. Controller --> pass the data to the Product class and return to Controller
3. Controller --> pass the data to the view

Hopes this helps you out
Reply
#4

(This post was last modified: 11-10-2015, 01:53 AM by sebastianvirlan.)

(11-10-2015, 01:16 AM)Martin7483 Wrote: In the world of MVC each request is routed to a Controller. You could ignore the M and V completely and do everything in your controller. But you will quickly see that this means duplicating a lot of code. So you start to use Models for Database communication. In your models you perform some logic to the DB results and return it to your controller. Again you will start to notice code duplication. So you start using helpers for common functions and libraries for more complex data handling. And thus you may start to use a business layer for your models.

I would say your Product class is a library and you pass a data package to this class. So how you call this could be
1. Controller --> request data from your model and return to Controller
2. Controller --> pass the data to the Product class and return to Controller
3. Controller --> pass the data to the view

Hopes this helps you out

Thank you. Helped a lot, see my last post with my class and tell me if I can refactor something.

Then in my controller I have:

PHP Code:
$best_offer         = new Product($this->products->best_offer(), 270);
$produse_noi        = new Product($this->produse->entries_by_limit(010null), 270);
$data['best_offer'] = $best_offer->product();
$data['produse_noi']= $produse_noi->products(); 

Is this the best practice MVC and OOP?
Reply
#5

i think your way of thinking is on the right way but needs to get organized

Your Problem is that you need sometimes methods or variables where it seems they don't belong to a model or a controller.
i try to explain it on your current example

First of all we need to adapt the MVC principle into a MVOC term.
make a folder in your application directory called objects

the next thing is you have to make sure that your objects get autoloaded
open your hooks.php in application/config/ and write the following down

PHP Code:
$hook['pre_system'][] = array(
    
'class' => 'AppAutoLoadObjects',
    
'function' => 'initialize',
    
'filename' => 'AppAutoLoadObjects.php',
    
'filepath' => 'hooks'
); 


after that create a class named AppAutoLoadObjects.php in your applications/hooks/ directory
this class should look like

PHP Code:
class AppAutoLoadObjects {

    public function 
initialize()
    {
        
spl_autoload_register(array($this,'autoloadCoreObjects'));
    }

    public function 
autoloadCoreObjects($class)
    {
        
$path = array(
            
'objects/',
        );

        foreach(
$path as $dir) {
            if (
file_exists(APPPATH.$dir.'/'.strtolower($class).'.php'))    require_once(APPPATH.$dir.'/'.strtolower($class).'.php');
        }
    }


now to your object

create a Product_Object in the application/objects/ directory
(be aware in order to avoid name collision add always the _Object Suffix to your Objects)

PHP Code:
class Product_Object
{
    private 
$rez;

    public function 
getImage()
    {
        if (
$this->nume_imagine)
        {
            
$strImage base_url("assets/uploads/".$this->id_produs."/".$this->getParsedImage());
        }
        else
        {
            
$strImage base_url('assets/images/no-product-image-available.png');
        }
        
        return 
$strImage;
    }
    
    public function 
setRez($rez)
    {
        
$this->rez $rez;
    }
    
    private function 
getParsedImage(){
 
       $image explode('.'$this->nume_imagine);
 
       return $image[0].'_'.$this->rez.'.'.$image[1];

 
   


your model should look like

PHP Code:
public function entries_by_limit($start$limit$order_by "order by id_produs asc"$rez
{
    
$this->db->select('a.*');
    
$this->db->select('b.nume_imagine'false);
    
$this->db->from("$this->_table a");
    
$this->db->join('imagini_produse b'"b.$this->_primary_key = a.id_produs""left");
    
$this->db->limit($limit$start);
    
$this->db->order_by($order_by);
    
$result $this->db->get();

    
$arrData = array();
    
    foreach(
$result->result("Product_Object") as $objProduct) {
        
$objProduct->setRez($rez);
        
$arrData[] = $objProduct;
    }
    
    return 
$arrData;


your controller function could be

PHP Code:
public function listProducts()
{
    
$arrProducts $this->produse->entries_by_limit((($page-1) * $config_pagina['per_page']), $config_pagina['per_page'], $order_by'270')
    
$arrViewData = array("produse" => $arrProducts);
    
    if (
count($arrProducts) > 0)
    {
        
$this->load->view("your_view_name"$arrViewData);
    }
    else
    {
        
$this->load->view("no_products");
    }


and finally your view
PHP Code:
<?php
foreach($produse AS $objProduct)
{
?>
    <img class="primary-image" src="<?=$objProduct->getImage(); ?>" alt="" />
<?php
}
?>


with this approach everything is on its own place
and if you want to manipulate product data you can do this in your own object and you could be sure - every time a product gets instantiated you have the right data and methods.
Reply
#6

I am not very convinced about this method because I must do a foreach in models. And let me tell you why:

in Products model I may have:

select_by_id
select_by_slug
select_by_category_id_by_limit
select_by_category_slug_by_limit
entries_by_limit

And think that I must make a foreach inside all this models. A lot of duplicate foreach ....
Reply
#7

I don't understand what you mean

in your example you have a Model which uses exactly the foreach approach


Quote:foreach($result->result() as $single) {...


and if you have a function where you know exactly that you expect only one result
than you can write something like 

PHP Code:
$result $this->db->get();
if (
$result->num_rows() == 1)
{
    
$objProduct $query->row(0"Product_Object");
    return 
$objProduct;
}
return 
false
Reply
#8

Yes my Model used the foreach and because of this I posted ...

Yes, sometimes I have result and sometimes row with 1 result.
Reply
#9

foreach loops in a model are perfectly fine
and if you are concerned about performance issues because you've to use this foreach in one of your views too - don't worry its absolutely no problem
Reply
#10

(This post was last modified: 11-11-2015, 01:06 AM by sebastianvirlan.)

(11-10-2015, 02:07 PM)dubefx Wrote: @sintakonte very interesting aproach, i learned something new today, so thanks. But CI3 already have this functionality custom_result_object and custom_row_object and can be used in your example model like:
Code:
public function entries_by_limit($start, $limit, $order_by = "order by id_produs asc", $rez)
{
   $this->db->select('a.*');
   $this->db->select('b.nume_imagine', false);
   $this->db->from("$this->_table a");
   $this->db->join('imagini_produse b', "b.$this->_primary_key = a.id_produs", "left");
   $this->db->limit($limit, $start);
   $this->db->order_by($order_by);
   $query = $this->db->get_compiled_select()
   $result = $this->db->query($query);
   return $result->custom_result_object('Produse_Object');
}
Autoload for _Object is still required, but if you don't want to register new autoload simply add at the end of Produse model the Produse_Object class and is done. Also you can access all CI mega object by adding:
Code:
   public function __get($name)
   {
      return get_instance()->$name;
   }
in Produse_Object class (in case you are not extending Produse class).[/code]

So is still need for hook? Please post your full final code. I don't see where you pass $rez.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB