views:

42

answers:

3

This has me beat. I'm trying to create an array of fields in cakePHP 1.2.5 & PHP 5.3.2 The array is zero based. On the first iteration, $count == 0. For some reason the string concatenation seems to convert this to null or unset which cake then interprets as "insert model name here", viz:

for($count=0;$count<$num;$count++)
{
   echo $form->input($count.'.NodeDescriptor.title');
}

<input name="data[NodeDescriptor][NodeDescriptor][title]" type="text" id="NodeDescriptorNodeDescriptorTitle" />
<input name="data[1][NodeDescriptor][title]" type="text" id="1NodeDescriptorTitle" /></div><tr><td><div class="input select">
...

I've tried casting the value, strval'ing it, single quotes, double quotes, double quotes and {} to no avail. Is this a PHP feature, a CakePHP unrobustness or me being dumb?

A: 

Can you stick to CakePHP conventions and put the model name first, followed by the index?

echo $form->input('NodeDescriptor.'.$count.'.title');
Mike
Leo
I was going by the format the `saveAll()` method expects.
Mike
I see your point and thanks for your comment, but I rarely use saveAll(), and as it has limited use anyway (as noted in the book) the parameter structure hardly constitutes a convention.None of this, however, gets to the nub of the problem which is that a zero index value is converted to the Model name, whereas a non-zero value retains its numerical value. I'm pretty sure it's not PHP. I don't think I'm being dumb, so I guess it must be a bug in CakePHP. Whether or not I'm supposed to do it that way, I can, but the behaviour is not consistent.
Leo
+1  A: 

First, it is a convention that if you are saving fields mapped to the same model and want multiple db inserts that the data array should be formatted as Mike expressed above:

i.e. Model.{n}.field

You can clearly see that they explicitly say that when you are saving the same fieldname in the same model multiple times that this is the convention as the title of the manual section is name "Field Naming Conventions"

http://book.cakephp.org/view/1390/Automagic-Form-Elements#Field-naming-convention-1391

You can't really call the input problem a CakePHP bug if the input method wasn't written to accommodate you using the method in an unintended fashion. The method explicitly splits the passed string on the "." character and assumes that if you are using a string with the "." character that you are intending to format your data array for saving using either Model->save or Model->saveAll

Secondly, when I test your code at my end it does exhibit a legit bug - it uses the numeric indexes I expect but duplicates them..

i.e. [0][0][Descriptor][title], 1[Descriptor][title]

When I move the index to where the save* functions expect it to be, the parsing is perfect.

i.e. [Descriptor][0][title], Descriptor[title]

So, if you want to use the helpers you should be using them in the ways they are intended to work. It isn't a bug if you invent your own edge case that wasn't intended to be supported by the helper to begin with.

Judging from your example - there is no reason not to use saveAll anyways. Do you have some reason for avoiding it; It seems to be the right way to do what you are asking.

** EDITED TO FIX TICKET http://cakephp.lighthouseapp.com/projects/42648/tickets/867 **

App this as app/views/app_view.php

<?php

App::import('View', 'View', false);

class AppView extends View {

    /**
     * Constructor
     *
     * @param object $controller
     */
    function __construct(&$controller){
            parent::__construct($controller);
    }

    /**
     * Temporary View::entity fix for 1.2.5
     * Returns the entity reference of the current context as an array of identity parts
     *
     * @return array An array containing the identity elements of an entity
     * @access public
     */
    function entity() {
        $assoc = ($this->association) ? $this->association : $this->model;
        if (!empty($this->entityPath)) {
            $path = explode('.', $this->entityPath);
            $count = count($path);
            if (
                ($count == 1 && !empty($this->association)) ||
                ($count == 1 && $this->model != $this->entityPath) ||
                ($count == 2 && !empty($this->fieldSuffix)) ||
                is_numeric($path[0]) && !empty($assoc)
            ) {
                array_unshift($path, $assoc);
            }
            return Set::filter($path);
        }
        return array_values(Set::filter(
            array($assoc, $this->modelId, $this->field, $this->fieldSuffix)
        ));
    }
}
?>

Tell your controller to use the view with it's public $view property.

<?php
    class FooController extends Controller {
        ...
        ...
        var $view = 'App';
        ...
        ...
    }
?>
Abba Bryant
The convention to which you refer also _explicitly_ states "...that can be saved in one shot with saveAll()...". I have good reasons for not using saveAll which I do not need to go into here.I was always taught to code for all exceptions, i.e. if a parameter is incorrect, handle it.My example was necessarily simplistic to avoid clouding the problem I was having, so do not judge from it. I would have thought that if Chris Hartjes was suggesting my approach, then it should be good to go. He was - and may still be - a Senior Developer at CakeDC, after all.
Leo
I don't get the bug you describe. Nor do I understand why you describe it as a legit bug (where mine isn't) because it doesn't behave as you expect while also saying it shouldn't be used that way. Some contradiction there, surely?
Leo
I didn't refer to the comment - I **referred to the documentation, which I linked - under the heading Form Element Naming Conventions - *Second, the bug I mentioned is a string parsing error - It is a bug withing the String class that handles the conversion of "." separated strings into array paths. Mine happens if I use the class directly or by proxy through the form helper.So no, I don't think I was being contradictory. You want to use it wrong, it works wrong. As for Chris suggesting your approach - that's nice but it *directly* contradicts the explicitly stated naming rules required...
Abba Bryant
...for the helper as *per the documentation* and last I checked the Cake codebase changes pretty quickly. If he suggested it then it only means that it might have worked at one point. If it doesn't work as expected anymore then you can't exactly bitch about it when you want to ignore the usage *specified clearly* in the documentation - in the source code - and from experienced cake users. I was just trying to help and explain why you hit an issue. If you don't like the advice don't use it.
Abba Bryant
Also, anything suggested by anyone 2 years ago on a google groups thread is likely to need to be a) double checked, and b) flat out wrong or out of date. CakeDC or not. Sorry for the triple comment but the word limit here is annoying and this wasn't worth a fresh "answer"
Abba Bryant
"I didn't refer to the comment... ": I didn't say that I said "..'convention'...". If you READ the convention in it's entirety, you'll see it applies to saveAll which I am not using.
Leo
"you can't exactly bitch about it": I was asking a question, not bitching. I can hardly ignore "usage specified clearly in the documentation" when it isn't specified FOR THE METHOD I'M USING.
Leo
Your response has been quite arrogant and offensive. If you're going to preach the manual, at least take the time to read it and my question properly.
Leo
The point is that the helper is only designed to save to the same field multiple times *when* the output is intended to be used by saveAll.The helper is built to generate html for specific use cases is and is moderately coupled to be useful to the majority of use cases when coupled to a model.If you can't use the helper because you couple your model and view differently then maybe you should simply write your own LeoFormHelper and override what you need to. I apologize if I sounded arrogant but you missed my point - which is that it's intended to be coupled and if you want it to work...
Abba Bryant
...out of the box for a set of requirements that it wasn't written for then shouldn't be calling it a "bug", because it isn't. It does a limited set of things and formats fields for model::save, and model::saveAll usage. It is dead simple to app::import the formhelper and extend it though. I suggest you do so, post it to githug or somesuch and let us all use it.
Abba Bryant
+1  A: 

I rebased the array at 1 and it works fine and as expected.

Leo
You should file a ticket on this. Index errors sound fishy and if it is a genuine bug I humbly eat my comments.
Abba Bryant
It would appear to be a bug. It has been fixed for 1.3 and a test case added for 1.2.7:http://cakephp.lighthouseapp.com/projects/42648/tickets/867-formhelper-string-concatenation-converting-zero-to-unset-in-cakephp
Leo