Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Item confirmation application
  • Hi, there. I'm new to FuelPHP and PHP in general. I understand the basic structure of how FuelPHP works, but I have a hard time figuring out the specifics on how database handling works between the model and the controller. In my database, I have an item category number. If wanted to have a search bar when you enter a category number, it populates a drop down menu for the number entered, how would I do that? 

    Model:
    class Item extends \Model {
    public static function select_one_item()
    {

    $itemQuery     = "";      
    $arryResult     = "";
    $itemId = "";

    $itemQuery = "some SQL commands";

    $arryResult = \DB::query($itemQuery)->execute();

        
            if(count($arryResult) >0 ){
                foreach($arryResult as $item)
                {
                 
                    $itemId= $item['item_id'];   
                }
            }
            return $itemId;

    }
    }

    Controller:

    use \Model\Item;

    class Controller_Item extends Controller_Search
    {
       ?????
    }

    I'm currently being outsourced working on this project for a company. I've been learning on the job, but it has been quite tough. The application I'm working on is a smaller part of a bigger application. Another app that was developed for the larger application used FuelPHP but the person who made it is no longer with the company. Up until now I have been looking at their code for guidance and trying to figure out FuelPHP works using it and the official documents. Any help would be greatly appreciated. Thank you.
  • HarroHarro
    Accepted Answer
    There are basically four ways to constuct models, and which one depends on your architecture choices.

    1) Use direct DB calls

    Which is what your example is using. In this case, a model is a class like all others, you have defined a static method "select_one_item" without arguments, so you call it like so:

    $result = Item::select_one_item();

    which is standard PHP.

    2) Use the Model_Crud base model


    This base model gives your models a basic ActiveRecord like interface, which you can call directly from your controller, or from methods inside the model if you prefer to abstract the calls away from the controller.

    3) Use the ORM base model.


    This base model gives your models a advanced ActiveRecord like interface, which supports relations, and which you can call directly from your controller, or from methods inside the model if you prefer to abstract the calls away from the controller.

    4) Use a combination of 1) and 2) or 3) or some other storage solutoin.

    Which is usually done for larger and/or more architected/designed applications.

    You use standard model classes to abstract all I/O away from the controller, standardize the response of your model classes, and in the model, you abstract the specific I/O away to Model_Crud or ORM (in case you use a database), or use Redis / Memcached /etc...

    BTW:

    In the code above, you don't need to loop and process the result, the DB execute() method already results a Dababase Result object you can return directly.
  • HarroHarro
    Accepted Answer
    Your question is "how do I implement this application function", which is very difficult to anwer because it depends on the application.

    - You need to have a user interface
    - The user needs to use that to post the category number
    - Your controller action (a generic action or a post action) method must grab and validate the input
    - It must call a model method to retrieve a key/value list of all items for this category in some order
    - this list can then be used to generate the dropdown with whatever frontend method your app uses
  • Thank you for the detailed response. Right now I want to just get a grasp on the basic usage so I think I'll stick with the DB call for now, but I think I'll try to implement  combination of the three methods you listed in the future. 

    I should have worded it a bit better. Thanks for correcting me.
    That makes complete sense. Right now I have a user interface created. Although, I'm trying to get a view style similar to https://fuelphp.com/docs/general/controllers/template.html. Right now, I'm having a hard time rendering the html when all the code is not in the index view and is broken up similar to that in the template controller documents. After I get that done, I'll try to implement the other 4 steps.
  • So I placed $result = Item::select_one_item(); in my model, but I'm still unsure how to actually display the data from the SQL query in my view.  Right now I just want to retrieve some data from an SQL query and then output it to the screen. Sorry for the dumb question. Not sure if I should be asking in another thread or what.
  • HarroHarro
    Accepted Answer
    Start with a var_dump($result), so you can see what actually is returned. 

    Depending on your config, it might be an array of records, or a Database result object. Which one it is defines how you access the data.

    If it is a database object, you can iterate over it, and get a row at the time:

    for ($result as $row)
    {
        // depending on the type of database object
        echo is_array($row) ? $row['field'] : $row->field;
    }

    The ORM always returns objects.
  • I see. If I wanted to start with var_dump($result), I would return var_dumb($result) in the function that is in my model, so that I can pass my data from my model to my controller, right?
    I would then read in my model file in my controller by having ```use \Model\Shelf;``` in the top of my controller file, correct? If the follow above is okay, I'm then a bit confused on how to send the results from the query that I have read into the controller to the view. Currently in my view:

    public function action_index()
        {
            // create the layout view
            $view = View::forge('shelf/index');

            $view->head = View::forge('common/head');
            $view->header = View::forge('common/header');
            $view->content = View::forge('common/content');
            $view->footer = View::forge('common/footer');

            // return the view object to the Request
            return $view;
        }

    I looked in the view documents online and something that might be useful was this

     $view->somevar = function() { return "somevalue"; };

    but I'm unsure if that is what I need. Thanks for taking the time to answer my questions. I really appreciate it.
  • If you want to send data to a view, you can simply assign it to the object:

    $view->content->data = $result;

    and then in the view iterate over it and generate the HTML.
  • I'm not sure exactly what content is here. It gave me an error, 'OutOfBoundsException [ Error ]:
    View variable is not set: content'' when I tried to use it so I removed it. However, it seems like $result is not being read into my controller from my model. I get the error,
    'Fuel\Core\PhpErrorException [ Notice ]:Undefined variable: result' .'

    Controller code:

    <?php

    use \Model\Shelf;

    class Controller_Shelf extends Controller_Template
    {
        public function action_index()
        {
            // create the layout view
            $view = View::forge('shelf/index');

            // assign global variables so all views have access to them
            $view->data = $result;
           
           
            //assign views as variables, lazy rendering
            $view->head = View::forge('common/head');
            $view->header = View::forge('common/header');
            $view->content = View::forge('common/content');
            $view->footer = View::forge('common/footer');

            // return the view object to the Request
            return $view;
        }
    }

    The model is being read into the controller by 'use \Model\Shelf;', right?
    Unless I'm missing something.

    Model code:

    <?php

    namespace Model;

    /* use ___PHPSTORM_HELPERS\object;
    use Fuel\Core\Asset_Instance; */

    class Shelf extends \Model {

        public static function get_results()
        {
      
            $result = DB::query('SELECT substring(cat.item_class_cd,1,1), cat.class_name
            from MASTER_DB.MS_CATEGORY cat
            where length(cat.item_class_cd) = 1');

            $result->execute();
            $result = Item::get_results();
           
            $output = var_dump($result);
            return $output;
        }
    }

    For out putting to an HTML I would just have

    foreach($reuslt as $item) {
        print $item;
    }

    in my HTML correct?
  • It looks like you are missing even the basic knowledge of PHP.

    "use" imports a classname into the current namespace, it doesn't do anything else, it is a declaration.

    Your code does

    $view->data = $result;

    while $result is never defined. You also assign it to the toplevel view (which I assume contains the page framework), while I assume you need to display the data in the content section of the page, which is $view->content, which is only defined below that line.

    I have also no clue what you want to do in your model, you run a query, then overwrite the $results with something from a similar named method in an Item class?

    And your output is correct when you spell $result correctly, when you pass $result with the correct name to a view (which you don't do anywhere, you pass it as "data", not as "result"), and when you add the code generating the HTML in the correct view file.
  • Yes, sorry. I only know the most basic of PHP. I'm still trying to learn. I've been looking at the PHP documentation to learn.

    I see.
    So does that mean I need to have $view->content above if I want to do something like
    $view->content->data = $result;  ?
    For example:

    $view->content = View::forge('common/content');
    $view->content->data = $results;

    I understand now that my model is pretty wonky. I want to get run a query and then output that data from that query to the screen. That's it.

    Ah, I miss typed there. Thanks.
    I think I understand. So in this case my code is:


    foreach($data as $item) {
        print $item;
    }

    because I am passing $result as 'data', right?
  • HarroHarro
    Accepted Answer
    Yes, as long as it is below where $view is created.

    As for the Model, I think this will do:

        public static function get_results()
        {
       
            $result = DB::query('SELECT substring(cat.item_class_cd,1,1), cat.class_name
            from MASTER_DB.MS_CATEGORY cat
            where length(cat.item_class_cd) = 1')->execute();

            return $result;
        }


    And yes, if you use

    $view->content->data = $results;

    you create a variable named "data" in the "content" view object, so that becomes $data in that view.
  • I see. Thanks :) I got output working to screen. Thanks for all the help!! I really appreciate it.
  • Hi there again. You mentioned in one of your first comments on how to implement what it is I want to do. Right, now I'm trying to figure out how to get post to work. I'm currently looking at https://fuelphp.com/docs/classes/input.html but I'm still a bit confused. How exactly are you supposed to use post($index = null, $default = null) ? Is this supposed to go in my view under like this?

    <label for="category">カテゴリ</label>
    <form action="content.php" method="post">
    <input type="text" name="category" <?php Input::post($data['id']) ?>><br/>

    data['id'] is the id number for the category and data['name'] is supposed to be the name of the category.

    <div class=" form-group">
    <select class="form-control form-control-sm">
    <?php
    Input::get(data['id']);
    foreach($data as $option){
    <option>$option['name']</option>
    }
    ?>
    </select>

    My code might be a bit confusing. If 0 though 6 is selected it will populate the drop down with the category name for the selected category ID number.



  • What do you mean with "post to work"? 

    Processing post data? Populating a form? Repopulating a form after a post?
  • Ah, I meant how do I use post. Sorry for not being clear.
    Um, processing post data and repopulating a form after post, I think is what I want.
    What I want to do is when a category number is input in the view, a category name will be returned in the same view via a drop down menu. So what I was trying to do was use 'post' to send my category id and use 'get' to retrieve the category name. I'm not sure if I need to use post to send data to the controller first or if I can just send it to the view? I read an answer to a StackExchange question that said you could do both. Sorry if this sounds confusing.
  • Accidentally commented twice.
  • Normally you don't use GET variables, Fuel uses URL segments that map to method arguments.

    Say you have

    Controller Test
    {
        public function action_go($parm1, $parm2 = null)
       {
       }
    }

    If you request "/test/go", you will get an error (as parm1 is required but missing.
    If you request "/test/go/1", $parm1 will contain "1".
    If you request "/test/go/1/page", $parm1 will contain "1", $parm2 will contain "page".

    For forms, it's better to use a Fieldset object, instead of doing everything by hand. That is not why you use a framework, right? A fieldset will take care of everything, from form and html generation to input validation and repopulation.


    It shows you how to deal with a form and post data using a fieldset.
  • For a fieldset wouldn't I have to declare all the category names in my
    database? I have a lot of category names so it seems like it would be
    difficult to do that.

    As far as form/html generation goes, I
    already made my html for my project. I basically only have one screen.
    It is just for item verification which includes a search bar for items
    (where you enter the category id, name of the product and maker),
    display of the item that needs to be verified, and a list of items
    (images) that are similar to the item that are trying to verify. Is a
    Fieldset object still the best choice to use here?

    Here's an image of the category id search part.
    https://imgur.com/a/ciLeEvS
  • Ok, not a problem, it only means you have to code everything manually.

    The process flow in the action method still applies.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion