We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Variables overwritten when using partial

I have what I think is a bug report, but I'd like a sanity check before filing one. It seems the inclusion of a partial causes a variable to be overwritten

This is a snippet of the relevant view code:

{% for key,class in [   'complete':'class-complete',
                        'registered':'class-reg',
                        'not_registered':'class-not_reg',
                        'admitted':'class-adm',
                        'applicant':'class-app',
                        'waitlisted':'class-wait',
                        'cancelled':'class-cancel'] %}
    <?php dump(array_keys($applicants)); ?>
    {% for Applicant in applicants[key] %}
        {{ partial('index/partials/applicant',['Applicant':Applicant,'class':class]) }}
    {% endfor %}
{% endfor %}

Snippet of output

File: /var/www/htdocs/pfir/app/views/compiled/index/c_index.phtml.php
Line: 75
Array
(
    [0] => complete
    [1] => applicant
    [2] => waitlisted
    [3] => cancelled
    [4] => admitted
    [5] => registered
    [6] => not_registered
)

File: /var/www/htdocs/pfir/app/views/compiled/index/c_index.phtml.php
Line: 75
Array
(
    [0] => complete
    [1] => applicant
    [2] => waitlisted
    [3] => cancelled
    [4] => admitted
    [5] => registered
    [6] => not_registered
)

File: /var/www/htdocs/pfir/app/views/compiled/index/c_index.phtml.php
Line: 75
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

Partialled applicant.phtml

<tr class = "{{ class }}" data-applicant-id = "{{ Applicant.id }}">
    <td class = "align-middle {% if Applicant.diffStatus() == constant('Model\Diff::STATUS_PROGRESS') %}diff-bg diff-progress{% elseif Applicant.diffStatus() == constant('Model\Diff::STATUS_COMPLETE') %}diff-bg diff-complete{% elseif Applicant.diffStatus() == constant('Model\Diff::STATUS_NEW') %}diff-bg{% endif %}">
        <div class = "custom-control custom-checkbox applicant-complete">
            <input type = "checkbox" class = "custom-control-input" id = "complete-{{ Applicant.id }}" />
            <label for="complete-{{ Applicant.id }}" class="custom-control-label">
                Complete
            </label>
        </div>
    </td>

    {% set Diffs = Applicant.getAssociativeDiffs() %}
    {% for field_name,field_title in constant('Model\Applicant::FIELDS') %}
        {% set cell_is_diff = Diffs[field_name] is defined %}
        <td {% if cell_is_diff %} class = "diff" {% endif %}>
            {{ Applicant.readAttribute(field_name) }}
            {% if cell_is_diff %}
                ( {{ Diffs[field_name].prev_value }} )
            {% endif %}
        </td>
    {% endfor %}
</tr>

You can see there's some raw PHP mixed in there for debugging. What should happen is the outer loop loops through each "classification", and the inner loop loops through all the applicants with that classification.

The outer loop hits the complete classification first, but the inner loop doesn't run because there are no "complete" Applicants (I know this because I checked the array in PHP land), therefore there is no {{ partial }} called. The outer loop then goes on to the applicant classification and since there are "applicant" Applicants, {{ partial }} gets called. Somehow applicants gets overwritten by the inclusion of the partial. If I comment out that {{ partial }} line (and add some other debugging code) the loops work just fine.

Am I missing something or is this the same problem as https://github.com/phalcon/cphalcon/issues/12648

use macros insteand of partials

I was using macros, but I need to be able to render the partial in a different controller&action, so it needs to be a discrete view file. I think I'm just going to use raw PHP to include() the template file, and adjust how I reference the variables.

Use other argument names for partial.

Use other argument names for partial.

I'm not sure what that would do? I'm not re-using any variable names already, so changing them shouldn't have any affect.

To be clear - I'm not really looking for a work-around. I already have one. I just want to see if there's a bug in my code that could be causing this, or if it really is a bug in Phalcon. Even if I was using the same variable names in a different scope, I shouldn't be experiencing this issue.



145.0k
Accepted
answer

It's bug in phalcon.

It's bug in phalcon.

Ok, thanks.

edited Sep '18

I mean you are re-using variable names, You have {% for Applicant in applicants[key] %} and then to partial you have again pass Applicant and class. Test it with:

`{{ partial('index/partials/applicant',['apl':Applicant,'cl':class]) }}`

<tr class = "{{ cl }}" data-applicant-id = "{{ apl.id }}">
    <td class = "align-middle {% if apl.diffStatus() == constant('Model\Diff::STATUS_PROGRESS') %}diff-bg diff-progress{% elseif apl.diffStatus() == constant('Model\Diff::STATUS_COMPLETE') %}diff-bg diff-complete{% elseif apl.diffStatus() == constant('Model\Diff::STATUS_NEW') %}diff-bg{% endif %}">
        <div class = "custom-control custom-checkbox applicant-complete">
            <input type = "checkbox" class = "custom-control-input" id = "complete-{{ apl.id }}" />
            <label for="complete-{{ apl.id }}" class="custom-control-label">
                Complete
            </label>
        </div>
    </td>

    {% set Diffs = apl.getAssociativeDiffs() %}
    {% for field_name,field_title in constant('Model\Applicant::FIELDS') %}
        {% set cell_is_diff = Diffs[field_name] is defined %}
        <td {% if cell_is_diff %} class = "diff" {% endif %}>
            {{ apl.readAttribute(field_name) }}
            {% if cell_is_diff %}
                ( {{ Diffs[field_name].prev_value }} )
            {% endif %}
        </td>
    {% endfor %}
</tr>

It should work like this, but yea, it's a bug.