ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Pulling Data as JSON | Template vs. Plugin

March 19, 2009 3:35am

Subscribe [5]
  • #1 / Mar 19, 2009 3:35am

    Toby Sommer

    27 posts

    Moved to HowTo by Moderator

    Hi everyone!

    For my application, I make use of Ajax. Therefore, I need to pull data from my database and send these data as JSON, so my jQuery can handle the response.
    You might ask, why I’m using JSON. Well, because JSON has low redundant data and it has a very low overhead, so it is very fast 😊

    Currently, I use a template to get this data. The template code looks like this:

    <?php
    global $DB, $IN;
    
    $list  = $IN->GBL('list', 'POST');
    $start = $IN->GBL('start', 'POST');
    $limit = $IN->GBL('limit', 'POST');
    $sort  = $IN->GBL('sort', 'POST');
    $dir   = $IN->GBL('dir', 'POST');
    $q     = $IN->GBL('q', 'POST');
    
    // search query
    if ($q && $q != '')
    {
        $q = $DB->escape_str($q);
        $where_part = " AND first_name LIKE '{$q}%' ";
        $where_part .= " OR last_name LIKE '{$q}%' ";
    }
    else
    {
        $where_part = '';
    }
    
    // all entries
    if ($limit == 'all')
    {
        $limit_part = '';
    }
    elseif (is_numeric($limit))
    {
        $limit_part = " LIMIT {$DB->escape_str($start)}, {$DB->escape_str($limit)}";
    }
    else
    {
        $limit_part = '';
    }
    
    $sql = "SELECT *
        FROM my_table
        WHERE lst = {$DB->escape_str($list)} {$where_part}
        ORDER BY {$DB->escape_str($sort)} {$DB->escape_str($dir)}
        {$limit_part}";
    
    $query = $DB->query($sql);
    
    $query_count = $DB->query("SELECT COUNT(*) AS count_total
        FROM _ns_hv_TS2
        WHERE lst = {$DB->escape_str($list)} {$where_part}");
    
    $count = 0;
    $i = 0;
    
    $json = array();
    $json['sql']         = $sql;
    $json['total_count'] = $query_count->result[0]['count_total'];
    $json['list']        = $list;
    $json['start']       = $start;
    $json['limit']       = $limit;
    $json['sort']        = $sort;
    $json['dir']         = $dir;
    if ($q) $json['q']   = $q;
    
    
    if ($query->num_rows > 0)
    {
        $json['x'] = array();
        foreach ($query->result as $row)
        {
            $json['x'][$i]['id']     = $row['id'];
            $json['x'][$i]['data_1'] = $row['data_1'];
            $json['x'][$i]['data_2'] = $row['data_2'];
            ++$i;
        }
    }
    
    echo json_encode($json);
    
    /* End of file get_geraete_ajax.php */
    /* Location: ./system/templates/json/get_data_1.php */
    ?>

    Of course, this does the job, but I wonder if there is a more elegant way to get such a JSON object?!

    I thought about a plugin which does the same job, the result is, that I can use this tag:

    {exp:export_format:json list="vegetables" start="0" limit="25" sort="id" dir="asc"}

    This works as it should: First the plugin checks if there are POSTed params, after this it checks the template parameters.

    The only problem is, that I still have to create a single template with just this one line of code, so I ask, how I can get rid of that?

    In the end, I want to call this via the following URL:

    <a href="http://mysite/export_format/json/data_to_pull/table_id/">http://mysite/export_format/json/data_to_pull/table_id/</a>

    I need some different JSON objects, e.g. one is just to count data. The difference should look like this:

    <a href="http://mysite/export_format/json/count/vegetables/4/">http://mysite/export_format/json/count/vegetables/4/</a>
    <a href="http://mysite/export_format/json/all_data/vegetables/4/">http://mysite/export_format/json/all_data/vegetables/4/</a>

    So with 1), I just get this: “{total_count:432}” and 2) should create a more complex JSON object; something like the template code I posted above.

    In the future I also want to have these features:

    <a href="http://mysite/export_format/xml/all_data_/vegetables/4/">http://mysite/export_format/xml/all_data_/vegetables/4/</a>
    <a href="http://mysite/export_format/excel/all_data_/vegetables/4/">http://mysite/export_format/excel/all_data_/vegetables/4/</a>
    <a href="http://mysite/export_format/pdf/all_data_/vegetables/4/">http://mysite/export_format/pdf/all_data_/vegetables/4/</a>


    - Can you tell me, which is the right way to code?
    - Plugin or template?
    - How can I pull data whithout using a template?
    - Any other ideas on this?


    Thank you very much.

  • #2 / Mar 19, 2009 10:12am

    ender

    1644 posts

    the only real difference I can think of is that your php code in template form has to be run using eval() calls, which adds some overhead to the processing.  I usually send my JSON back via plugins and oneliner templates, haven’t really had an issue with it.

    the only way you’d be able to avoid a template would be to use some php code in a file outside of EE’s control.  if you have your htaccess file removing index.php you’d have to create another rule to exclude sending calls to this php file to index.php.

  • #3 / Mar 19, 2009 11:08am

    Toby Sommer

    27 posts

    ender, thanks for your feedback.

    I will use those “one-line-templates” as well using plugins. Specially because the {exp:ClassName:MethodName}-Syntax suits my needs.

    This is what I’ve done so far:

    <?php
    class Foobar
    {
        private $_list;
        private $_start;
        private $_limit;
        private $_sort;
        private $_dir;
        private $_q;
        
        
        public function __construct()
        {
            $this->_list  = $this->_post_or_segment(5, 'list', false);
            $this->_start = $this->_post_or_segment(6, 'start', 0);
            $this->_limit = $this->_post_or_segment(7, 'limit', 25);
            $this->_sort  = $this->_post_or_segment(8, 'sort', 'id');
            $this->_dir   = $this->_post_or_segment(9, 'dir', 'ASC');
            $this->_q     = $this->_post_or_segment(10, 'q', '');
            
        }
        /* END */
    
        public function count()
        {
            global $DB, $IN;
    
            $sql = "SELECT COUNT(*) AS count_total
                FROM my_table
                WHERE lst = {$DB->escape_str($this->_list)}";
    
            $query_count = $DB->query($sql);
    
            $count = 0;
            $i = 0;
    
            $json = array();
            $json['sql']         = $sql;
            $json['total_count'] = $query_count->result[0]['count_total'];
    
            return json_encode($json);
        }
        /* END */
        
        
        public function json()
        {
            global $DB, $IN;
    
            // search query
            if ($this->_q && $this->_q != '')
            {
                $this->_q = $DB->escape_str($this->_q);
                $where_part = " AND first_name LIKE '{$this->_q}%' ";
                $where_part .= " OR last_name LIKE '{$this->_q}%' ";
            }
            else
            {
                $where_part = '';
            }
    
            // all entries
            if ($this->_limit == 'all')
            {
                $limit_part = '';
            }
            elseif (is_numeric($this->_limit))
            {
                $limit_part = " LIMIT {$DB->escape_str($this->_start)}, {$DB->escape_str($this->_limit)}";
            }
            else
            {
                $limit_part = '';
            }
    
            $sql = "SELECT *
                FROM my_table
                WHERE lst = {$DB->escape_str($this->_list)} {$where_part}
                ORDER BY {$DB->escape_str($this->_sort)} {$DB->escape_str($this->_dir)}
                $limit_part";
    
            $query = $DB->query($sql);
    
            $query_count = $DB->query("SELECT COUNT(*) AS count_total
                FROM _ns_hv_TS2
                WHERE lst = {$DB->escape_str($this->_list)} {$where_part}");
    
            $count = 0;
            $i = 0;
    
            $json = array();
            $json['sql']         = $sql;
            $json['total_count'] = $query_count->result[0]['count_total'];
            $json['list']        = $this->_list;
            $json['start']       = $this->_start;
            $json['limit']       = $this->_limit;
            $json['sort']        = $this->_sort;
            $json['dir']         = $this->_dir;
            if ($this->_q) $json['q']   = $this->_q;
    
    
            if ($query->num_rows > 0)
            {
                $json['x'] = array();
                foreach ($query->result as $row)
                {
                    $json['x'][$i]['id']     = $row['id'];
                    $json['x'][$i]['data_1'] = $row['data_1'];
                    $json['x'][$i]['data_2'] = $row['data_2'];
                    ++$i;
                }
            }
    
            return json_encode($json);
        }
        /* END */
    
    
        private function _post_or_segment($seg = 0, $name = '', $default = '')
        {
            global $IN;
    
            if ($IN->GBL($name, 'POST') && trim($IN->GBL($name, 'POST')) != '')
            {
                $return_data = $IN->GBL($name, 'POST');
            }
            elseif ($seg > 0 && $IN->fetch_uri_segment($seg) && trim($IN->fetch_uri_segment($seg)) != '')
            {
                $return_data = $IN->fetch_uri_segment($seg);
            }
            else
            {
                $return_data = $default;
            }
    
            return $return_data;
        }
        
        
    }
    // END CLASS
    ?>

    The problem is, that I can’t access my POSTed variables.

    How do you access ‘em? Or did you use segments, without any POSTs? Or GETs instead of segments?

  • #4 / Mar 19, 2009 11:26am

    Sue Crocker

    26054 posts

    Hey, guys—we’ve reached HowTo status. Moving so you can continue the conversation.

  • #5 / Mar 19, 2009 12:14pm

    Toby Sommer

    27 posts

    I’m fine working with segments only… Therefore I changed my constructor:

    public function __construct()
        {
            global $IN;
            
            $this->_list  = $IN->fetch_uri_segment('4');
            $this->_start = $IN->fetch_uri_segment('5') ? $IN->fetch_uri_segment('5') : '0';
            $this->_limit = $IN->fetch_uri_segment('6') ? $IN->fetch_uri_segment('6') : 'all';
            $this->_sort  = $IN->fetch_uri_segment('7') ? $IN->fetch_uri_segment('7') : 'id';
            $this->_dir   = $IN->fetch_uri_segment('8') ? $IN->fetch_uri_segment('8') : 'ASC';
            $this->_q     = $IN->fetch_uri_segment('9') ? $IN->fetch_uri_segment('9') : '';
        }
        /* END */


    Any ideas how to do it “nicer”? -thanks

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases