_template = APP_PATH . 'Common/Builder/Layout/' . MODULE_MARK . '/list.html'; } /** * 设置页面标题 * @param $title 标题文本 * @return $this * */ public function setMetaTitle($meta_title) { $this->_meta_title = $meta_title; return $this; } /** * 加入一个列表顶部工具栏按钮 * 在使用预置的几种按钮时,比如我想改变新增按钮的名称 * 那么只需要$builder->addTopButton('add', array('title' => '换个马甲')) * 如果想改变地址甚至新增一个属性用上面类似的定义方法 * @param string $type 按钮类型,主要有add/resume/forbid/recycle/restore/delete/self七几种取值 * @param array $attr 按钮属性,一个定了标题/链接/CSS类名等的属性描述数组 * @return $this * */ public function addTopButton($type, $attribute = null) { switch ($type) { case 'addnew': // 添加新增按钮 // 预定义按钮属性以简化使用 $my_attribute['title'] = '新增'; $my_attribute['class'] = 'btn btn-primary-outline btn-pill'; $my_attribute['href'] = U(MODULE_NAME . '/' . CONTROLLER_NAME . '/add'); /** * 如果定义了属性数组则与默认的进行合并 * 用户定义的同名数组元素会覆盖默认的值 * 比如$builder->addTopButton('add', array('title' => '换个马甲')) * '换个马甲'这个碧池就会使用山东龙潭寺的十二路谭腿第十一式“风摆荷叶腿” * 把'新增'踢走自己霸占title这个位置,其它的属性同样道理 */ if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'resume': // 添加启用按钮(禁用的反操作) //预定义按钮属性以简化使用 $my_attribute['title'] = '启用'; $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-success-outline btn-pill ajax-post confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; // 要操作的数据模型 $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'resume', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的新增按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'forbid': // 添加禁用按钮(启用的反操作) // 预定义按钮属性以简化使用 $my_attribute['title'] = '禁用'; $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-warning-outline btn-pill ajax-post confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'forbid', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的新增按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } //这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'recycle': // 添加回收按钮(还原的反操作) // 预定义按钮属性以简化使用 $my_attribute['title'] = '回收'; $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-danger-outline btn-pill ajax-post confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'recycle', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的新增按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'restore': // 添加还原按钮(回收的反操作) // 预定义按钮属性以简化使用 $my_attribute['title'] = '还原'; $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-success-outline btn-pill ajax-post confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'restore', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的新增按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'delete': // 添加删除按钮(我没有反操作,删除了就没有了,就真的找不回来了) // 预定义按钮属性以简化使用 $my_attribute['title'] = '删除'; $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-danger-outline btn-pill ajax-post confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'delete', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的新增按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; case 'self': //添加自定义按钮(第一原则使用上面预设的按钮,如果有特殊需求不能满足则使用此自定义按钮方法) // 预定义按钮属性以简化使用 $my_attribute['target-form'] = 'ids'; $my_attribute['class'] = 'btn btn-danger-outline btn-pill'; // 如果定义了属性数组则与默认的进行合并 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } else { $my_attribute['title'] = '该自定义按钮未配置属性'; } // 这个按钮定义好了把它丢进按钮池里 $this->_top_button_list[] = $my_attribute; break; } return $this; } /** * 设置搜索参数 * @param $title * @param $url * @return $this * */ public function setSearch($title, $url) { $this->_search = array('title' => $title, 'url' => $url); return $this; } /** * 设置Tab按钮列表 * @param $tab_list Tab列表 array( * 'title' => '标题', * 'href' => 'http://www.corethink.cn' * ) * @param $current_tab 当前tab * @return $this * */ public function setTabNav($tab_list, $current_tab) { $this->_tab_nav = array( 'tab_list' => $tab_list, 'current_tab' => $current_tab, ); return $this; } /** * 加一个表格标题字段 * */ public function addTableColumn($name, $title, $type = null, $param = null) { $column = array( 'name' => $name, 'title' => $title, 'type' => $type, 'param' => $param, ); $this->_table_column_list[] = $column; return $this; } /** * 表格数据列表 * */ public function setTableDataList($table_data_list) { $this->_table_data_list = $table_data_list; return $this; } /** * 表格数据列表的主键名称 * */ public function setTableDataListKey($table_data_list_key) { $this->_table_data_list_key = $table_data_list_key; return $this; } /** * 加入一个数据列表右侧按钮 * 在使用预置的几种按钮时,比如我想改变编辑按钮的名称 * 那么只需要$builder->addRightpButton('edit', array('title' => '换个马甲')) * 如果想改变地址甚至新增一个属性用上面类似的定义方法 * 因为添加右侧按钮的时候你并没有办法知道数据ID,于是我们采用__data_id__作为约定的标记 * __data_id__会在display方法里自动替换成数据的真实ID * @param string $type 按钮类型,edit/forbid/recycle/restore/delete/self六种取值 * @param array $attr 按钮属性,一个定了标题/链接/CSS类名等的属性描述数组 * @return $this * */ public function addRightButton($type, $attribute = null) { switch ($type) { case 'edit': // 编辑按钮 // 预定义按钮属性以简化使用 $my_attribute['name'] = 'edit'; $my_attribute['title'] = '编辑'; $my_attribute['class'] = 'label label-primary-outline label-pill'; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/edit', array($this->_table_data_list_key => '__data_id__') ); /** * 如果定义了属性数组则与默认的进行合并 * 用户定义的同名数组元素会覆盖默认的值 * 比如$builder->addRightButton('edit', array('title' => '换个马甲')) * '换个马甲'这个碧池就会使用山东龙潭寺的十二路谭腿第十一式“风摆荷叶腿” * 把'新增'踢走自己霸占title这个位置,其它的属性同样道理 */ if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; case 'forbid': // 改变记录状态按钮,会更具数据当前的状态自动选择应该显示启用/禁用 //预定义按钮属 $my_attribute['type'] = 'forbid'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['forbid0']['name'] = 'forbid'; $my_attribute['forbid0']['title'] = '启用'; $my_attribute['forbid0']['class'] = 'label label-success-outline label-pill ajax-get confirm'; $my_attribute['forbid0']['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'resume', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); $my_attribute['forbid1']['name'] = 'forbid'; $my_attribute['forbid1']['title'] = '禁用'; $my_attribute['forbid1']['class'] = 'label label-warning-outline label-pill ajax-get confirm'; $my_attribute['forbid1']['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'forbid', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); /** * 如果定义了属性数组则与默认的进行合并 * 用户定义的同名数组元素会覆盖默认的值 * 比如$builder->addRightButton('edit', array('title' => '换个马甲')) * '换个马甲'这个碧池就会使用山东龙潭寺的十二路谭腿第十一式“风摆荷叶腿” * 把'新增'踢走自己霸占title这个位置,其它的属性同样道理 */ if ($attribute['forbid0'] && is_array($attribute['forbid0'])) { $my_attribute['forbid0'] = array_merge($my_attribute['forbid0'], $attribute['forbid0']); } if ($attribute['forbid1'] && is_array($attribute['forbid1'])) { $my_attribute['forbid1'] = array_merge($my_attribute['forbid1'], $attribute['forbid1']); } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; case 'recycle': //预定义按钮属 $my_attribute['type'] = 'recycle'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['recycle1']['name'] = 'recycle'; $my_attribute['recycle1']['title'] = '回收'; $my_attribute['recycle1']['class'] = 'label label-danger-outline label-pill ajax-get confirm'; $my_attribute['recycle1']['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'recycle', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); $my_attribute['recycle-1']['name'] = 'restore'; $my_attribute['recycle-1']['title'] = '还原'; $my_attribute['recycle-1']['class'] = 'label label-success-outline label-pill ajax-get confirm '; $my_attribute['recycle-1']['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'restore', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); /** * 如果定义了属性数组则与默认的进行合并 * 用户定义的同名数组元素会覆盖默认的值 * 比如$builder->addRightButton('edit', array('title' => '换个马甲')) * '换个马甲'这个碧池就会使用山东龙潭寺的十二路谭腿第十一式“风摆荷叶腿” * 把'新增'踢走自己霸占title这个位置,其它的属性同样道理 */ if ($attribute['recycle-1'] && is_array($attribute['recycle-1'])) { $my_attribute['recycle-1'] = array_merge($my_attribute['recycle-1'], $attribute['recycle-1']); } if ($attribute['recycle1'] && is_array($attribute['recycle1'])) { $my_attribute['recycle1'] = array_merge($my_attribute['recycle1'], $attribute['recycle1']); } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; case 'restore': // 预定义按钮属性以简化使用 $my_attribute['name'] = 'restore'; $my_attribute['title'] = '还原'; $my_attribute['class'] = 'label label-success-outline label-pill ajax-get confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'restore', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的顶部按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; case 'delete': // 预定义按钮属性以简化使用 $my_attribute['name'] = 'delete'; $my_attribute['title'] = '删除'; $my_attribute['class'] = 'label label-danger-outline label-pill ajax-get confirm'; $my_attribute['model'] = $attribute['model'] ?: CONTROLLER_NAME; $my_attribute['href'] = U( MODULE_NAME . '/' . CONTROLLER_NAME . '/setStatus', array( 'status' => 'delete', 'ids' => '__data_id__', 'model' => $my_attribute['model'], ) ); // 如果定义了属性数组则与默认的进行合并,详细使用方法参考上面的顶部按钮 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; case 'self': // 预定义按钮属性以简化使用 $my_attribute['name'] = 'self'; $my_attribute['class'] = 'label label-default'; // 如果定义了属性数组则与默认的进行合并 if ($attribute && is_array($attribute)) { $my_attribute = array_merge($my_attribute, $attribute); } else { $my_attribute['title'] = '该自定义按钮未配置属性'; } // 这个按钮定义好了把它丢进按钮池里 $this->_right_button_list[] = $my_attribute; break; } return $this; } /** * 设置分页 * @param $page * @return $this * */ public function setTableDataPage($table_data_page) { $this->_table_data_page = $table_data_page; return $this; } /** * 修改列表数据 * 有时候列表数据需要在最终输出前做一次小的修改 * 比如管理员列表ID为1的超级管理员右侧编辑按钮不显示删除 * @param $page * @return $this * */ public function alterTableData($condition, $alter_data) { $this->_alter_data_list[] = array( 'condition' => $condition, 'alter_data' => $alter_data, ); return $this; } /** * 设置额外功能代码 * @param $extra_html 额外功能代码 * @return $this * */ public function setExtraHtml($extra_html) { $this->_extra_html = $extra_html; return $this; } /** * 设置页面模版 * @param $template 模版 * @return $this * */ public function setTemplate($template) { $this->_template = $template; return $this; } /** * 显示页面 * */ public function display() { // 编译data_list中的值 foreach ($this->_table_data_list as &$data) { // 编译表格右侧按钮 if ($this->_right_button_list) { foreach ($this->_right_button_list as $right_button) { // 禁用按钮与隐藏比较特殊,它需要根据数据当前状态判断是显示禁用还是启用 if ($right_button['type'] === 'forbid') { $right_button = $right_button['forbid' . $data['status']]; } if ($right_button['type'] === 'recycle') { if ($data['status'] === '0' || $data['status'] === '1') { $right_button = $right_button['recycle1']; } else { $right_button = $right_button['recycle' . $data['status']]; } } // 将约定的标记__data_id__替换成真实的数据ID $right_button['href'] = preg_replace( '/__data_id__/i', $data[$this->_table_data_list_key], $right_button['href'] ); // 编译按钮属性 $right_button['attribute'] = $this->compileHtmlAttr($right_button); $data['right_button'][$right_button['name']] = $right_button; } } /** * 修改列表数据 * 有时候列表数据需要在最终输出前做一次小的修改 * 比如管理员列表ID为1的超级管理员右侧编辑按钮不显示删除 */ if ($this->_alter_data_list) { foreach ($this->_alter_data_list as $alter) { if ($data[$alter['condition']['key']] === $alter['condition']['value']) { if ($alter['alter_data']['right_button']) { foreach ($alter['alter_data']['right_button'] as &$val) { if (!$val['attribute']) { $val['href'] = preg_replace( '/__data_id__/i', $data[$this->_table_data_list_key], $val['href'] ); $val['attribute'] = $this->compileHtmlAttr($val); // 编译按钮属性 } } } $data = array_merge($data, $alter['alter_data']); } } } // 根据表格标题字段指定类型编译列表数据 foreach ($this->_table_column_list as &$column) { switch ($column['type']) { case 'status': switch ($data[$column['name']]) { case '-1': $data[$column['name']] = ''; break; case '0': $data[$column['name']] = ''; break; case '1': $data[$column['name']] = ''; break; } break; case 'byte': $data[$column['name']] = $this->formatBytes($data[$column['name']]); break; case 'icon': $data[$column['name']] = ''; break; case 'date': $data[$column['name']] = time_format($data[$column['name']], 'Y-m-d'); break; case 'datetime': $data[$column['name']] = time_format($data[$column['name']]); break; case 'time': $data[$column['name']] = time_format($data[$column['name']]); break; case 'avatar': $data[$column['name']] = ''; break; case 'picture': $data[$column['name']] = ''; break; case 'pictures': if (!is_array($data[$column['name']])) { $temp = explode(',', $data[$column['name']]); } $data[$column['name']] = ''; break; case 'type': $form_item_type = C('FORM_ITEM_TYPE'); $data[$column['name']] = $form_item_type[$data[$column['name']]][0]; break; case 'callback': // 调用函数 if (is_array($column['param'])) { $data[$column['name']] = call_user_func_array($column['param'], array($data[$column['name']])); } else { $data[$column['name']] = call_user_func($column['param'], $data[$column['name']]); } break; } if (is_array($data[$column['name']]) && $column['name'] !== 'right_button') { $data[$column['name']] = implode(',', $data[$column['name']]); } } } //编译top_button_list中的HTML属性 if ($this->_top_button_list) { foreach ($this->_top_button_list as &$button) { $button['attribute'] = $this->compileHtmlAttr($button); } } $this->assign('meta_title', $this->_meta_title); // 页面标题 $this->assign('top_button_list', $this->_top_button_list); // 顶部工具栏按钮 $this->assign('search', $this->_search); // 搜索配置 $this->assign('tab_nav', $this->_tab_nav); // 页面Tab导航 $this->assign('table_column_list', $this->_table_column_list); // 表格的列 $this->assign('table_data_list', $this->_table_data_list); // 表格数据 $this->assign('table_data_list_key', $this->_table_data_list_key); // 表格数据主键字段名称 $this->assign('table_data_page', $this->_table_data_page); // 表示个数据分页 $this->assign('right_button_list', $this->_right_button_list); // 表格右侧操作按钮 $this->assign('alter_data_list', $this->_alter_data_list); // 表格数据列表重新修改的项目 $this->assign('extra_html', $this->_extra_html); //是否ajax提交 // 显示页面 $template = CONTROLLER_NAME . '/' . ACTION_NAME; if (is_file($this->view->parseTemplate($template))) { parent::display(); } else { $this->assign('is_builder', 'list'); // Builder标记 parent::display($this->_template); } } //编译HTML属性 protected function compileHtmlAttr($attr) { $result = array(); foreach ($attr as $key => $value) { $value = htmlspecialchars($value); $result[] = "$key=\"$value\""; } $result = implode(' ', $result); return $result; } /** * 格式化字节大小 * @param number $size 字节数 * @param string $delimiter 数字和单位分隔符 * @return string 格式化后的带单位的大小 */ protected function formatBytes($size, $delimiter = '') { $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); for ($i = 0; $size >= 1024 && $i < 5; $i++) { $size /= 1024; } return round($size, 2) . $delimiter . $units[$i]; } }