0

基本上我有一个源于 Joomla 3.1 的 JSON 处理的问题,尽管因为我无法隔离它,所以我提出了这个问题以寻求指导。如果这是我应该报告的错误或我的应用程序中的某些内容,这将有望用于隔离。

Joomla 3.1 似乎有一个插件,或者在默认$model->save()$table->save(). 这可能会导致在保存任何类型的页面时对 JSON 字段进行不必要的添加。到目前为止,通过他们的代码查看我一直无法隔离它(女巫让我想到插件,虽然我只启用了默认值。)

所以这是一个问题:

Joomla 是否对表单输入进行任何 JSON 处理?如果可以,可以禁用吗?

为了澄清我个人的问题,我有一个骨架组件保存功能(将一些次要值保存到数据库中,一列是 JSON 字段)。它使用JModelAdmin并通过它JTable来处理内容的保存。然而,JSON 数组中的每个项目(它是一个对象数组)在每次保存时都会被复制。考虑到它是一个隐藏形式的字符串,当它被保存时,在进程的某个地方它被解析成一个 php 数组并由 Joomla 复制。由于实际保存过程中没有自定义代码,因此 Joomla 可能需要在其他地方编辑 JSON 值,而我的组件触发了它。

这是表单 xml,如果这与它有任何关系,values隐藏的表单字段是“应该”包含 json 的内容,它在您保存之前一直有效。那是 JSON 数组中的每个索引都重复的时候。

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset>
        <field name="id"  type="text" class="readonly" label="JGLOBAL_FIELD_ID_LABEL"
            description ="JGLOBAL_FIELD_ID_DESC" size="10" default="0"
            readonly="true" />

        <field name="name" type="text" label="COM_HELLO_COMPANY_FIELD_NAME_LABEL"
            description="COM_HELLO_COMPANY_FIELD_NAME_DESC" class="input-xlarge" size="30"
            required="true" labelclass="control-label" />

        <field name="state" type="list" label="JSTATUS"
            description="JFIELD_PUBLISHED_DESC" class="span12 small"
            filter="intval" size="1" default="1"
        >
            <option value="1">
                JPUBLISHED</option>
            <option value="0">
                JUNPUBLISHED</option>
            <option value="2">
                JARCHIVED</option>
            <option value="-2">
                JTRASHED</option>
        </field>

        <field
            name="buttonspacer"
            description="JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION"
            type="spacer" />

        <field name="created" type="calendar" label="COM_HELLO_FIELD_CREATED_LABEL"
            description="COM_CONTENT_FIELD_CREATED_DESC" class="inputbox" size="22"
            format="%Y-%m-%d %H:%M:%S" filter="user_utc" labelclass="control-label" />

        <field name="created_by" type="user"
            label="COM_HELLO_FIELD_CREATED_BY_LABEL" description="COM_HELLO_FIELD_CREATED_BY_DESC" labelclass="control-label" />

        <field name="modified" type="calendar" class="readonly"
            label="JGLOBAL_FIELD_MODIFIED_LABEL" description="COM_HELLO_FIELD_MODIFIED_DESC"
            size="22" readonly="true" format="%Y-%m-%d %H:%M:%S" filter="user_utc" labelclass="control-label" />

        <field name="modified_by" type="user"
            label="JGLOBAL_FIELD_MODIFIED_BY_LABEL"
            class="readonly"
            readonly="true"
            filter="unset"
            labelclass="control-label"
         />

        <field name="checked_out" type="hidden" filter="unset" />

        <field name="values" type="hidden" />

        <field name="checked_out_time" type="hidden" filter="unset" />

        <field name="publish_up" type="calendar"
            label="COM_HELLO_FIELD_PUBLISH_UP_LABEL" description="COM_HELLO_FIELD_PUBLISH_UP_DESC"
            class="inputbox" format="%Y-%m-%d %H:%M:%S" size="22"
            filter="user_utc" labelclass="control-label" />

        <field name="publish_down" type="calendar"
            label="COM_HELLO_FIELD_PUBLISH_DOWN_LABEL" description="COM_HELLO_FIELD_PUBLISH_DOWN_DESC"
            class="inputbox" format="%Y-%m-%d %H:%M:%S" size="22"
            filter="user_utc" labelclass="control-label" />

        <field name="assesments" type="text" label="COM_HELLO_COMPANY_FIELD_ASSESEMENTS_LABEL"
            description="COM_HELLO_COMPANY_FIELD_ASSESEMENTS_DESC" class="readonly" size="6"
            readonly="true" filter="unset" />

    </fieldset>
</form>

这是我的页面的edit.php。它使用 JSON 来更新值字段,相同的概念在站点的前端完美运行,只有管理员方面存在问题。

<?php
defined('_JEXEC') or die;

JHtml::_('behavior.formvalidation');
JHtml::_('behavior.keepalive');
//JHtml::_('formbehavior.chosen', 'select');

$app = JFactory::getApplication();
$input = $app->input;
if(!empty($this->item->values)){
    $values = json_decode($this->item->values);
}else{
    $values = array();
}
function setupSelect($selected = 0,$savedValues){
    $selectOptions = '';
    foreach($savedValues as $value){
        $selectOptions .= '<option value="'.$value->id.'"'.($value->id==$selected?' selected="selected"':'').'>'.$value->name.'</option>';
    }
    return $selectOptions;
}
?>
<script type="text/javascript">
    Joomla.submitbutton = function(task){
        if(task == 'company.cancel' || document.formvalidator.isValid(document.id('item-form'))){
            Joomla.submitform(task, document.getElementById('item-form'));
        }
    }
</script>
<form action="<?php echo JRoute::_('index.php?option=com_hello&view=company&layout=edit&id='.(int) $this->item->id); ?>" method="post" name="adminForm" id="item-form" class="form-validate">

    <?php echo JLayoutHelper::render('joomla.edit.item_title', $this); ?>

    <div class="row-fluid">
        <!-- Begin Content -->
        <div class="span10 form-horizontal">
            <?php echo JHtml::_('bootstrap.startTabSet', 'myTab', array('active' => 'general')); ?>

                <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'general', JText::_('COM_HELLO_VALUE_DETAILS', true)); ?>
                    <fieldset class="adminform">
                        <div class="control-group form-inline">
                            <?php echo $this->form->getLabel('name'); ?> <?php echo $this->form->getInput('name'); ?>
                        </div>
                        <div>Core Values:</div>
                        <div class="control-group form-inline">
                            <div id="core-values" class="accordion">
                                <?php
                                if(count($values)):
                                    foreach($values as $value):
                                        $id = uniqid();
                                        ?>
                                        <div class="core-value row-fluid">
                                            <div class="accordion-group core-value span9" style="padding:0;">
                                                <div class="accordion-heading">
                                                    <a class="accordion-toggle" data-toggle="collapse" data-parent="#core-values" href="#collapse<?php echo $id; ?>">
                                                        <select class="value-select">
                                                            <option value="0"><?php echo JText::_('COM_HELLO_CORE_VALUES_SELECT_NONE'); ?></option>
                                                            <?php echo setupSelect($value->id,$this->values); ?>
                                                        </select>
                                                        <span class="pull-right" style="height:28px;line-height:28px;">
                                                            <span class="icon-plus main"></span>
                                                        </span>
                                                    </a>
                                                    <span class="clearfix"></span>
                                                </div>
                                                <div id="collapse<?php echo $id; ?>" class="accordion-body collapse">
                                                    <div class="accordion-inner">
                                                        <input type="text" class="outcome-input input-block-level" placeholder="Outcome Statement" value="<?php echo $value->outcome; ?>">
                                                        <ul class="behaviors">
                                                            <?php
                                                            $num = 6;
                                                            for($i=0;$i<$num;$i++): 
                                                            ?>
                                                            <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior" value="<?php echo empty($value->behaviors[$i])?'':$value->behaviors[$i]; ?>"></li>
                                                            <?php endfor; ?>
                                                            <?php if(count($value->behaviors)>6): 
                                                                for($i=6;$i<count($value->behaviors);$i++): 
                                                            ?>
                                                            <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior" value="<?php echo empty($value->behaviors[$i])?'':$value->behaviors[$i]; ?>"></li>
                                                            <?php endfor; 
                                                            endif; ?>
                                                        </ul>
                                                        <div class="clearfix"></div>
                                                        <button type="button" class="btn new-value2 pull-right"><span class="icon-plus no-stop"></span></button>
                                                        <div class="clearfix"></div>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="span3" style="line-height:44px;">
                                                <button type="button" class="btn rm-value"><span class="icon-minus"></span></button>
                                            </div>
                                        </div>
                                        <?php
                                    endforeach;
                                endif;
                                $id = uniqid();
                                ?>
                                <div class="core-value row-fluid">
                                    <div class="accordion-group span9" style="padding:0;">
                                        <div class="accordion-heading">
                                            <a class="accordion-toggle" data-toggle="collapse" data-parent="#core-values" href="#collapse<?php echo $id; ?>">
                                                <select class="value-select">
                                                    <option value="0"><?php echo JText::_('COM_HELLO_CORE_VALUES_SELECT_NONE'); ?></option>
                                                    <?php echo setupSelect(0,$this->values); ?>
                                                </select>
                                                <span class="pull-right" style="height:28px;line-height:28px;">
                                                    <span class="icon-plus main"></span>
                                                </span>
                                            </a>
                                            <span class="clearfix"></span>
                                        </div>
                                        <div id="collapse<?php echo $id; ?>" class="accordion-body collapse">
                                            <div class="accordion-inner">
                                                <input type="text" class="outcome-input input-block-level" placeholder="Outcome Statement">
                                                <ul class="behaviors">
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                    <li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>
                                                </ul>
                                                <div class="clearfix"></div>
                                                <button type="button" class="btn new-value2 pull-right"><span class="icon-plus no-stop"></span></button>
                                                <div class="clearfix"></div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="span3" style="line-height:44px;">
                                        <button type="button" class="btn rm-value"><span class="icon-minus"></span></button>
                                        <button type="button" class="btn new-value"><span class="icon-plus"></span></button>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <?php echo $this->form->getInput('values'); ?>
                    </fieldset>
                <?php echo JHtml::_('bootstrap.endTab'); ?>
                <?php echo JHtml::_('bootstrap.addTab', 'myTab', 'publishing', JText::_('COM_HELLO_FIELDSET_PUBLISHING', true)); ?>
                    <div class="row-fluid">
                        <div class="span6">
                            <div class="control-group">
                                <div class="control-label">
                                    <?php echo $this->form->getLabel('id'); ?>
                                </div>
                                <div class="controls">
                                    <?php echo $this->form->getInput('id'); ?>
                                </div>
                            </div>
                            <div class="control-group">
                                <?php echo $this->form->getLabel('created_by'); ?>
                                <div class="controls">
                                    <?php echo $this->form->getInput('created_by'); ?>
                                </div>
                            </div>
                            <div class="control-group">
                                <?php echo $this->form->getLabel('created'); ?>
                                <div class="controls">
                                    <?php echo $this->form->getInput('created'); ?>
                                </div>
                            </div>
                        </div>
                        <div class="span6">
                            <div class="control-group">
                                <?php echo $this->form->getLabel('publish_up'); ?>
                                <div class="controls">
                                    <?php echo $this->form->getInput('publish_up'); ?>
                                </div>
                            </div>
                            <div class="control-group">
                                <?php echo $this->form->getLabel('publish_down'); ?>
                                <div class="controls">
                                    <?php echo $this->form->getInput('publish_down'); ?>
                                </div>
                            </div>
                            <?php if ($this->item->modified_by) : ?>
                                <div class="control-group">
                                    <?php echo $this->form->getLabel('modified_by'); ?>
                                    <div class="controls">
                                        <?php echo $this->form->getInput('modified_by'); ?>
                                    </div>
                                </div>
                                <div class="control-group">
                                    <?php echo $this->form->getLabel('modified'); ?>
                                    <div class="controls">
                                        <?php echo $this->form->getInput('modified'); ?>
                                    </div>
                                </div>
                            <?php endif; ?>

                            <?php if ($this->item->assesments) : ?>
                                <div class="control-group">
                                    <div class="control-label">
                                        <?php echo $this->form->getLabel('assesments'); ?>
                                    </div>
                                    <div class="controls">
                                        <?php echo $this->form->getInput('assesments'); ?>
                                    </div>
                                </div>
                            <?php endif; ?>
                        </div>
                    </div>
                <?php echo JHtml::_('bootstrap.endTab'); ?>
            <?php echo JHtml::_('bootstrap.endTabSet'); ?>
            <input type="hidden" name="task" value="" />
            <input type="hidden" name="return" value="<?php echo $input->getCmd('return');?>" />
            <?php echo JHtml::_('form.token'); ?>
        </div>
        <!-- End Content -->
        <!-- Begin Sidebar -->
            <?php echo JLayoutHelper::render('joomla.edit.details', $this); ?>
        <!-- End Sidebar -->
    </div>
</form>
<script>
var template = jQuery('.core-value:last').clone();
function setupButton(){
    jQuery('.new-value').on('click',function(){
        var clone = template.clone();
        clone.find('.accordion-body').attr('id','collapse'+new Date().getTime());
        clone.find('.accordion-toggle').attr('href','#collapse'+new Date().getTime());
        jQuery(this).parent().parent().after(clone);
        jQuery(this).remove();
        setupButton();
        setupRm();
    });
}
function setupRm(){
    jQuery('.rm-value').each(function(){
        jQuery(this).off('click').on('click',function(){
            var root = jQuery(this).parent().parent();
            if(jQuery('.core-value').length==1){
                root.replaceWith(template.clone());
                setupButton();
                setupRm();
            }else{
                root.remove();
            }
        });
    });
}
function parseBehaviors(root){
    var beh = [];
    root.find('li').each(function(){
        if(jQuery(this).find('.behaviors-input').val()){
            beh.push(jQuery(this).find('.behaviors-input').val());
        }
    });
    return beh;
}

jQuery(document).ready(function(){
    jQuery('.new-value2').on('click',function(){
        var root = jQuery(this).parent();
        root.find('.behaviors').append('<li><input type="text" class="behaviors-input input-block-level" placeholder="Behavior"></li>');
    });
    setupButton();
    setupRm();
    jQuery('.value-select').on('click',function(event){
        event.stopPropagation();
    });
    jQuery('#core-values').sortable();
    jQuery('#core-values').on('shown',function(event){
        jQuery(event.target).parent().find('.icon-plus.main').removeClass('icon-plus').addClass('icon-minus');
    }).on('hidden',function(event){
        jQuery(event.target).parent().find('.icon-minus.main').removeClass('icon-minus').addClass('icon-plus');
    });

    var setRefresh = setInterval(function(){
        var arr = [];
        jQuery('.core-value').each(function(){
            var obj = {};
            if(jQuery(this).find('.value-select option:selected').val()!=0){
                obj.id=jQuery(this).find('.value-select option:selected').val();
                obj.name=jQuery.trim(jQuery(this).find('.value-select option:selected').text());
                obj.outcome=jQuery(this).find('.outcome-input').val();
                obj.behaviors=parseBehaviors(jQuery(this).find('.behaviors'));
                arr.push(obj);
            }
        });
        var parse = JSON.stringify(arr);
        jQuery('#jform_values').val(parse);
    },200);
});
</script>

整个事情作为一个非常动态和压缩的自定义表单输入。话虽这么说,我必须将 JSON 作为字符串提供,因为我自己处理它真的没有意义,所以我不费心在模型/表中做任何保存覆盖作为 joomla 的默认函数“应该管用。我的下一步是几乎完全覆盖 JTable/JModelAdmin 以确保我解决了这个问题(尽管我的代码中仍有一部分可能是这个问题的来源,尽管经过几个小时的搜寻,我已经几乎放弃了希望在那)。

我也将此添加到 Joomla 问题跟踪器

追踪器

在那里,我包含了几个屏幕截图。尽管它链接到相同的东西,但也将其作为问题发布在 cms 存储库上。

GitHub

无论哪种方式,如果找不到答案,我都会以一种或另一种方式解决这个问题,我感谢任何可以提供帮助的人,因为这是该组件中的一个严重错误,不一定是 Joomla,但如果它确实是 3.1 的错误,我可以想象一下,我将是第一个遇到这种情况的人。

4

0 回答 0