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.

DMZ 1.7.1 (DataMapper OverZealous Edition)

March 14, 2010 11:43pm

Subscribe [104]
  • #871 / Sep 08, 2011 1:49pm

    tomdelonge

    60 posts

    Edit: never mind, I found it. I knew I’d seen it before; I just couldn’t find it in the documentation: “Get Rules”

    So I’m trying to have a field in a model that will store an array. Since I need to serialize it in order to store it, I don’t want to always run serialize() before I save it and unserialize() every time I pull it out. I think I can see how to add a serialize() function to the validation so that it is always put in the database correctly, but is there a way to always have it unserialize on the way back out of the database (get()) . Or should I do this a different way?

  • #872 / Nov 22, 2011 4:35pm

    fermar

    5 posts

    First of all: I wasn’t quite sure where to put this issue, it’s Datamapper extension related issue, so I’ll try here.

    I found that the datamapper extension json has a bug or a misbehavior. The function all_to_json returns the json object enclosed in unnecessary escaped double-quotes, then javascript in client side can’t parse it correctly, this doesn’t happen with the basic function to_json, this one (that returns the first object in json format) works just fine.

    I tried to debug the extension code, couldn’t find what’s going on.

    I solved it not converting to all_to_json but to an array with the array extension:
    all_to_array, and then, using json_encode() over this array, this works fine and I think that’s the key to know what can be happening with the all_to_json code.

    well, thanks for all your work

  • #873 / Nov 22, 2011 4:44pm

    WanWizard

    4475 posts

    I’ve been looking at the code, but I can’t see where double quotes would be escaped.
    I don’t have any issue using the result client-side.

    You don’t have anything running that would escape output? Which PHP version are you using?

  • #874 / Nov 22, 2011 5:22pm

    fermar

    5 posts

    Which PHP version are you using?

    PHP/5.3.4
    —————————————
    For debugging purposes:

    in my “clientes” Controller:

    public function getClientes() {
        $clientes = new Cliente()//this is my model;
        $clientes->select('id , apellido');
        $clientes->order_by('apellido');
        $clientes->get();
        $data['clientesarr'] = $clientes->all_to_array(array('id','apellido'),true);
        $data['clientesjson'] = $clientes->all_to_json(array('id','apellido'),true);
        //$this->firephp->log($data['clientes'],'datos');
        $this->load->view('ajax/clientes_view',$data);    
      }

    then, in the “clientes_view” (just this):

    echo json_encode($clientesarr);
    echo "
    ";
    echo $clientesjson;

    so, executing the function in the browser (/index.php/clientes/getClientes) I’ll see both results. I’m getting:

    [{"id":1,"apellido":"Fulanito"},{"id":3,"apellido":"Griffin"},{"id":2,"apellido":"Simpson"}]
    [ “{\"id\":1,\"apellido\":\"Fulanito\"}”, “{\"id\":3,\"apellido\":\"Griffin\"}”, “{\"id\":2,\"apellido\":\"Simpson\"}” ]

    source code:

    [{"id":1,"apellido":"Fulanito"},{"id":3,"apellido":"Griffin"},{"id":2,"apellido":"Simpson"}]
    [
      "{\"id\":1,\"apellido\":\"Fulanito\"}",
      "{\"id\":3,\"apellido\":\"Griffin\"}",
      "{\"id\":2,\"apellido\":\"Simpson\"}"
    ]

    First I thought that it would have something to do with the way json_encode()function worked (maybe some encoding option), but now I saw that using it directly in the view there was no problem, then, has to be something with the way in all_to_json function makes an array of json objects (calling to_json into a foreach structure) and then doing a to_json to this arrary of json objects.

    thanks for your concern

     

  • #875 / Nov 22, 2011 5:40pm

    WanWizard

    4475 posts

    The reason why they are escaped is that the entire output (inside the square brackets) is between quotes, to the quotes inside that string MUST be escaped.

    Question is, where do these quotes come from, as the extension doesn’t do much more then iterating over the object and calling json_encode().

    Start by removing the TRUE from all_to_json(), to stop the extension formatting it. The TRUE on all_to_array() doesn’t do anything, it doesn’t have a second parameter. Then do a

    var_dump($data['clientesjson']);

    in your controller to rule out any issues with the view, or other post processing code that may interface. This way you are sure it’s the extension.

    Also, what is the result if you use to_json(), and convert only the current record?

  • #876 / Nov 22, 2011 6:42pm

    fermar

    5 posts

    The “true” as a second parameter ended there because all the testing, took it out but nothing changes.

    Question is, where do these quotes come from, as the extension doesn’t do much more then iterating over the object and calling json_encode()

    They come from the to_json output, as you will see at next.

    Now:
    Controller:

    $data['clientesjson'] = $clientes->all_to_json(array('id','apellido'));
        $data['onejson'] = $clientes->to_json(array('id','apellido'));
        $data['clientesarr'] = $clientes->all_to_array(array('id','apellido'));
        $data['onearr'] = $clientes->to_array(array('id','apellido'));
        echo var_dump($data['clientesjson']).'
    ';
        echo var_dump($data['onejson']).'
    ';
        echo var_dump($data['clientesarr']).'
    ';
        echo var_dump(json_encode($data['clientesarr'])).'
    ';
        echo var_dump($data['onearr']).'
    ';
        echo var_dump(json_encode($data['onearr']));

    browser output:

    1st) string(116) “[”{\"id\":1,\"apellido\":\"Fulanito\"}”,”{\"id\":3,\"apellido\":\"Griffin\"}”,”{\"id\":2,\"apellido\":\"Simpson\"}”]”

    2nd) string(30) “{"id":1,"apellido":"Fulanito"}”

    3rd) array(3) { [0]=> array(2) { ["id"]=> int(1) ["apellido"]=> string(8) "Fulanito" } [1]=> array(2) { ["id"]=> int(3) ["apellido"]=> string(7) "Griffin" } [2]=> array(2) { ["id"]=> int(2) ["apellido"]=> string(7) "Simpson" } }

    4th) string(92) “[{"id":1,"apellido":"Fulanito"},{"id":3,"apellido":"Griffin"},{"id":2,"apellido":"Simpson"}]”

    5th) array(2) { ["id"]=> int(1) ["apellido"]=> string(8) "Fulanito" }

    6th) string(30) “{"id":1,"apellido":"Fulanito"}”

    The thing is that the 4th result is a valid array of three json objects (in json format), but the 1st (again in json format) is just an array of three strings.

    I think that the problem is to make an array of json objects (enclosed each one between double quotes, because apparently that’s how json_encode works), and then json_encode this array (that’s what all_to_json).

    I’m quite sure that all_to_json is not returning what is expected (an array of json objects) but an array of string that contains the data but has to be parsed ad hoc.
    what do you think?

    thanks again,

     

  • #877 / Nov 23, 2011 9:34am

    WanWizard

    4475 posts

    If I look at the code, to_json() works as it should. It fetches the objects properties, stores them into an array, then returns json_encode() of that array.

    In all_to_json(), the code iterates over the object, and calls to_json() on each object found, with the instruction NOT to encode the result. After iteration, the result is a multi-dimensional array, with an array for each object in the resultset. Only then the entire result is json_encode()‘d.

    If I look at your results, it looks like every individual object is encoded, and then the result encoded again. Which is not what the code on my system is doing.

    Which version of DataMapper are you working with (as you post in the 1.7.1 thread, which is an ancient version)?

  • #878 / Nov 23, 2011 10:09am

    fermar

    5 posts

    I’m using DM 1.8.1

    It seems that the json extension code in your system is different than mine.
    all_to_json actually calls to_json on each object found, but to_json definetely json_encode each object, and that is the problem.
    what do you mean by:

    with the instruction NOT to encode the result

    Here’s the pastebin with te code, (I just copy-pasted it from the last version available in datamapper site download page DMZ 1.8.1)

    Maybe this already been fixed in branch DM 2.0?

    thanks

  • #879 / Nov 23, 2011 10:33am

    WanWizard

    4475 posts

    Hmm… Looks like it was fixed but never pushed to the repo.

    Mine says (on L#53):

    $result[] = $o->to_json($fields, FALSE, TRUE);

    which disables the intermediate encoding.

  • #880 / Nov 23, 2011 10:48am

    fermar

    5 posts

    well, mystery solved!

    Is there any chance I could get the fixed json extension code?, I’d like to use all_to_json function as had planned. (maybe a patebin with the new code?)

    thanks a lot.

  • #881 / Nov 23, 2011 11:24am

    WanWizard

    4475 posts

    I’ll have to see where it comes from. I took this code from the 2.0 branch, but I’m sure I didn’t test any extensions in that branch (except array), and I didn’t do the update there.

    I’ll try to find the time to push the update to bitbucket later today.

  • #882 / Nov 25, 2011 8:22pm

    Daniel Peraza

    31 posts

    Hello, I just wanted to ask for a mor detailed example of how related fields validation works, since here doesn’t say anything about what the ‘group’ key neither, the ‘Group’ label means.

  • #883 / Nov 26, 2011 4:21am

    WanWizard

    4475 posts

    The idea here is that the ‘User’ object has a has_one or has_many called ‘Group’.

    DataMapper will check if the related object is present, i.e. if there is a group related to the loaded user.

  • #884 / Nov 26, 2011 4:27am

    Daniel Peraza

    31 posts

    But ‘User’ and ‘Group’ are other DataMapper instances right? I’m sorry, but it’s the first time I use this pattern, and I can’t avoid thinking in an ActiveRecord manner, where everything relates directly to database tables and columns.

  • #885 / Nov 26, 2011 7:31am

    WanWizard

    4475 posts

    ‘User’ and ‘Group’ are DataMapper models (classes that extend DataMapper), and they must have a relationship.

    In other words, this must work:

    $user = new User();
    
    // get a user
    $user->where('name', 'John')->limit(1)->get();
    
    // retrieve this users groups
    $user->group->get();
    
    // show the first group
    echo $user->group->name;

    In DataMapper, a model maps to a database table, and every instance of the model is an object representing either a single row, or a collection of rows from that table.

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

ExpressionEngine News!

#eecms, #events, #releases