简体   繁体   English

如何通过 PHP 将序列化嵌套可排序数据保存到 MySQL 表?

[英]How to Save Serialized Nested Sortable Data to MySQL Table Via PHP?

在此处输入图片说明

Can someone help me to save data from with below format to MySQL data in CodeIgniter?有人可以帮我将以下格式的数据保存到 CodeIgniter 中的 MySQL 数据吗?

data: "list[1]=null&list[7]=1&list[4]=1&list[5]=null&list[3]=5&list[2]=null&list[6]=2"

I have a MySQL table named as menu:我有一个名为 menu 的 MySQL 表:

CREATE TABLE `menu` (
  `menu_id` int(11) NOT NULL,
  `menu_parent` int(11) NOT NULL,
  `menu_name` varchar(30) NOT NULL,
  `menu_url` varchar(60) NOT NULL,
  `menu_icon` varchar(50) NOT NULL,
  `menu_order` int(11) NOT NULL,
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


INSERT INTO `menu` (`menu_id`, `menu_parent`, `menu_name`, `menu_url`, `menu_icon`, `menu_order`, `created`, `updated`) VALUES
(1, 0, 'Data Master', 'javascript:void(0);', '', 1, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(2, 0, 'Transaksi', 'javascript:void(0);', '', 4, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(3, 1, 'Jenis Layanan', 'jenis-layanan', '', 6, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(4, 1, 'Outlet', 'admin/outlet', '', 7, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(5, 0, 'Data Konfigurasi', 'javascript:void(0);', '', 3, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(6, 1, 'Menu', 'menu', '', 5, '2020-08-23 01:49:55', '2020-08-23 10:11:00'),
(7, 1, 'Jenis Jabatan', 'admin/jenis-jabatan', '', 2, '2020-08-23 01:49:55', '2020-08-23 10:11:00');

I use jQuery plugin nestedSortable to dynamically re-arrange the menu hierarchy and position as below:我使用 jQuery 插件nestedSortable来动态重新排列菜单层次结构和位置,如下所示:

$('ol.sortable').nestedSortable({
    disableNesting: 'no-nest',
    forcePlaceholderSize: true,
    handle: 'div',
    helper: 'clone',
    items: 'li',
    maxLevels: 3,
    opacity: .6,
    placeholder: 'placeholder',
    revert: 250,
    tabSize: 25,
    tolerance: 'pointer',
    toleranceElement: '> div'
});

This is the code to try saving to database:这是尝试保存到数据库的代码:

$(document).on('click', 'a#ubahPosisi', function(){
    var serialized = $('ol.sortable').nestedSortable('serialize');
    $.ajax({
        type: 'POST',
        url: '<?php echo base_url('Menu/UpdatePosisiMenu');?>',
        data: {data:serialized},
        dataType: 'JSON',
        cache: false,
        success: function(response) {
        alert(response);
        }
    });
});

This my CI model for menu:这是我的菜单 CI 模型:

public function GetClientMenu($orderby = 'menu_order') {
    $query = $this->db->order_by($orderby, 'ASC')->get('menu');
    $arrData = $query->result();
    $arrTreeById = [];
    $arrChildIds = [];

    foreach($arrData AS $objItem) {
    $arrTreeById[$objItem->menu_id] = $objItem;
    $objItem->arrChilds = [];
    }

    foreach($arrTreeById AS $objItem) {
    if (isset($arrTreeById[$objItem->menu_parent])) {
        $arrTreeById[$objItem->menu_parent]->arrChilds[] = $objItem;
        $arrChildIds[] = $objItem->menu_id;
    }
    }

    array_walk($arrChildIds, function($val) use (&$arrTreeById) {
     unset($arrTreeById[$val]);
    });
    return $arrTreeById;
}

public function UpdatePosisiMenu($data = [], $id) {
    return $this->db->update('menu', $data, ['menu_id' => $id]);
}

And this is how I pass it to variable:这就是我将它传递给变量的方式:

$this->data['menus'] = $this->m_menu->GetClientMenu('menu_order');

And, this is the view:而且,这是观点:

<ol class="sortable ui-sortable mjs-nestedSortable-branch mjs-nestedSortable-expanded">
    <?php if (count($menus) > 0): foreach ($menus as $menu):?>
    <li id="list_<?php echo $menu->menu_id;?>">
        <div class="menu-handle clearfix">
        <div class="menu-title pull-left">(<?php echo $menu->menu_id;?>) <?php echo $menu->menu_name;?></div>
        <div class="menu-option pull-right">
            <span><i class="glyphicon glyphicon-remove"></i></span>
        </div>
        </div>
        <?php if (count($menu->arrChilds) > 0):?>
            <ol class="submenu">
            <?php foreach ($menu->arrChilds as $submenu):?>
                <li id="list_<?php echo $submenu->menu_id;?>">
                    <div class="menu-handle clearfix">
                <div class="menu-title pull-left">(<?php echo $submenu->menu_id;?>) <?php echo $submenu->menu_name;?></div>
                <div class="menu-option pull-right">
                    <span><i class="glyphicon glyphicon-remove"></i></span>
                </div>
                </div>
            </li>
            <?php endforeach;?>
            </ol>
        <?php endif;?>
        </li>
    <?php endforeach; endif;?>
</ol>

And, lastly the CI controller to execute the saving:最后,CI 控制器执行保存:

public function UpdatePosisiMenu() {
    $data = $this->input->post(null);
        $sort = [];
        if (!empty($data)) {
        foreach ($data as $id => $ParentID) {
            $ParentID = ($ParentID === null) ? 0 : $ParentID;
            if (!array_key_exists($ParentID, $sort)) {
                $sort[$ParentID] = 1;
            }
            $this->m_menu->UpdatePosisiMenu(['menu_parent' => $ParentID, 'menu_order' => $sort[$ParentID]], $id);
            $sort[$ParentID]++;
        }           
    }   
}

And, I got this foreach error during saving:而且,我在保存过程中遇到了这个 foreach 错误:

A PHP Error was encountered
Severity: Warning
Message: Invalid argument supplied for foreach()
Filename: controllers/Menu.php
......

I fixed this issue with this update:我通过此更新解决了这个问题:

  1. table schema still is the same表架构仍然相同

  2. modification for the jQuery script: jQuery 脚本的修改:

     var menuarray; $('ol.sortable').nestedSortable({ disableNesting: 'no-nest', forcePlaceholderSize: true, handle: 'div', helper: 'clone', items: 'li', maxLevels: 5, opacity: .6, placeholder: 'placeholder', revert: 250, tabSize: 25, tolerance: 'pointer', toleranceElement: '> div', relocate: function(){ menuarray = $(this).nestedSortable('serialize'); console.log(menuarray); } }); $(document).on('click', 'a#ubahPosisi', function(){ $.ajax({ type: 'POST', url: '<?php echo base_url('Menu/UpdatePosisiMenu');?>', data: {data:menuarray}, dataType: 'JSON', cache: false, success: function(response) { if (response.success == true ) { window.location.reload(); } } }); });
  3. create helpers that will be used to build the menu contents创建将用于构建菜单内容的助手

    function prepareList(array $items, $pid = 0) { $output = array(); foreach ($items as $item) { if ((int) $item['menu_parent'] == $pid) { if ($children = prepareList($items, $item['menu_id'])) { $item['children'] = $children; } $output[] = $item; } } return $output; } function nav($menu_items, $child = false) { $output = ''; if (count($menu_items) > 0) { $output .= ($child === false) ? '<ol class="sortable">' : '<ol>' ; foreach ($menu_items as $item) { $output .= '<li id="list_' . $item['menu_id'] . '">'; $output .= '<div class="menu-handle clearfix">'; $output .= '<div class="menu-title pull-left">(' . $item['menu_id'] . ') ' . $item['menu_name'] . '</div>'; $output .= '<div class="menu-option pull-right"><span><i class="glyphicon glyphicon-remove"></i></span></div>'; $output .= '</div>'; if (isset($item['children']) && count($item['children'])) { $output .= nav($item['children'], true); } $output .= '</li>'; } $output .= '</ol>'; } return $output; }
  4. modify the model code修改型号代码

    public function buildMenu() { $this->db->select('menu_id, menu_parent, menu_url, menu_name, menu_order'); $this->db->order_by('menu_parent, menu_order'); $menuItems = $this->db->get('menu')->result_array(); return prepareList($menuItems); }
  5. grab the menu data in controller and view the menu contents in respective view file在控制器中抓取菜单数据并在相应的视图文件中查看菜单内容

    <?php echo nav($menus);?>
  6. and finally the magic code to save the menu group or order as you wish最后是根据需要保存菜单组或订单的魔术代码

    public function UpdatePosisiMenu() { $data = isset($_REQUEST['data'])? $_REQUEST['data'] : ''; $status = ['success' => false]; parse_str($data, $arr); if (isset($arr['list'])) { array_walk($arr['list'], function(&$val, $key){ $this->m_menu->UpdatePosisiMenu(['menu_parent' => $val, 'updated' => date('Ymd H:i:s')], $key); }); $status['success'] = true; } echo json_encode($status); }

And, this is how it looks now:而且,这就是它现在的样子:

( https://www.flickr.com/photos/189950440@N02/50283999368 ) ( https://www.flickr.com/photos/189950440@N02/50283999368 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM