<?php<liu21st@gmail.com>namespace Think\Model;
use Think\Model;
class ViewModel extends Model
{
protected $viewFields = array();
protected function _checkTableInfo()
{}
public function getTableName()
{
if (empty($this->trueTableName)) {
$tableName = '';
foreach ($this->viewFields as $key => $view) {
if (isset($view['_table'])) {
$tableName .= $view['_table'];
$prefix = $this->tablePrefix;
$tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function ($match) use ($prefix) {return $prefix . strtolower($match[1]);}, $tableName);
} else {
$class = parse_res_name($key, C('DEFAULT_M_LAYER'));
$Model = class_exists($class) ? new $class() : M($key);
$tableName .= $Model->getTableName();
}
$tableName .= !empty($view['_as']) ? ' ' . $view['_as'] : ' ' . $key;
$tableName .= !empty($view['_on']) ? ' ON ' . $view['_on'] : '';
$type = !empty($view['_type']) ? $view['_type'] : '';
$tableName .= ' ' . strtoupper($type) . ' JOIN ';
$len = strlen($type . '_JOIN ');
}
$tableName = substr($tableName, 0, -$len);
$this->trueTableName = $tableName;
}
return $this->trueTableName;
}
protected function _options_filter(&$options)
{
if (isset($options['field'])) {
$options['field'] = $this->checkFields($options['field']);
} else {
$options['field'] = $this->checkFields();
}
if (isset($options['group'])) {
$options['group'] = $this->checkGroup($options['group']);
}
if (isset($options['where'])) {
$options['where'] = $this->checkCondition($options['where']);
}
if (isset($options['order'])) {
$options['order'] = $this->checkOrder($options['order']);
}
}
private function _checkFields($name, $fields)
{
if (false !== $pos = array_search('*', $fields)) {
$fields = array_merge($fields, M($name)->getDbFields());
unset($fields[$pos]);
}
return $fields;
}
protected function checkCondition($where)
{
if (is_array($where)) {
$fields = $field_map_table = array();
foreach ($this->viewFields as $key => $val) {
$table_alias = isset($val['_as']) ? $val['_as'] : $key;
$val = $this->_checkFields($key, $val);
foreach ($val as $as_name => $v) {
if (is_numeric($as_name)) {
$fields[] = $v; $field_map_table[] = $table_alias; } else {
$fields[$as_name] = $v;
$field_map_table[$as_name] = $table_alias;
}
}
}
$where = $this->_parseWhere($where, $fields, $field_map_table);
}
return $where;
}
private function _parseWhere($where, $fields, $field_map_table)
{
$view = array();
foreach ($where as $name => $val) {
if ('_complex' == $name) {
foreach ($val as $k => $v) {
if (false === strpos(substr($k, 0, 1), '_')) {
if (false !== $field = array_search($k, $fields, true)) { $k = is_numeric($field) ? $field_map_table[$field] . '.' . $k : $field_map_table[$field] . '.' . $field; }
} else if (is_array($v)) {
$v = $this->_parseWhere($val[$k], $fields, $field_map_table);
}
$view[$name][$k] = $v;
}
} else {
if (strpos($name, '|')) {
$arr = explode('|', $name);
foreach ($arr as $k => $v) {
if (false !== $field = array_search($v, $fields, true)) {
$arr[$k] = is_numeric($field) ? $field_map_table[$field] . '.' . $v : $field_map_table[$field] . '.' . $field;
}
}
$view[implode('|', $arr)] = $val;
} else if (strpos($name, '&')) {
$arr = explode('&', $name);
foreach ($arr as $k => $v) {
if (false !== $field = array_search($v, $fields, true)) {
$arr[$k] = is_numeric($field) ? $field_map_table[$field] . '.' . $v : $field_map_table[$field] . '.' . $field;
}
}
$view[implode('&', $arr)] = $val;
} else {
if (false !== $field = array_search($name, $fields, true)) {
$name = is_numeric($field) ? $field_map_table[$field] . '.' . $name : $field_map_table[$field] . '.' . $field;
}
$view[$name] = $val;
}
}
}
return $view;
}
protected function checkOrder($order = '')
{
if (is_string($order) && !empty($order)) {
$orders = explode(',', $order);
$_order = array();
foreach ($orders as $order) {
$array = explode(' ', trim($order));
$field = $array[0];
$sort = isset($array[1]) ? $array[1] : 'ASC';
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
if (false !== $_field = array_search($field, $val, true)) {
$field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field;
break;
}
}
$_order[] = $field . ' ' . $sort;
}
$order = implode(',', $_order);
}
return $order;
}
protected function checkGroup($group = '')
{
if (!empty($group)) {
$groups = explode(',', $group);
$_group = array();
foreach ($groups as $field) {
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
if (false !== $_field = array_search($field, $val, true)) {
$field = is_numeric($_field) ? $k . '.' . $field : $k . '.' . $_field;
break;
}
}
$_group[] = $field;
}
$group = implode(',', $_group);
}
return $group;
}
protected function checkFields($fields = '')
{
if (empty($fields) || '*' == $fields) {
$fields = array();
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
foreach ($val as $key => $field) {
if (is_numeric($key)) {
$fields[] = $k . '.' . $field . ' AS ' . $field;
} elseif ('_' != substr($key, 0, 1)) {
if (false !== strpos($key, '*') || false !== strpos($key, '(') || false !== strpos($key, '.')) {
$fields[] = $key . ' AS ' . $field;
} else {
$fields[] = $k . '.' . $key . ' AS ' . $field;
}
}
}
}
$fields = implode(',', $fields);
} else {
if (!is_array($fields)) {
$fields = explode(',', $fields);
}
$array = array();
foreach ($fields as $key => $field) {
if (strpos($field, '(') || strpos(strtolower($field), ' as ')) {
$array[] = $field;
unset($fields[$key]);
}
}
foreach ($this->viewFields as $name => $val) {
$k = isset($val['_as']) ? $val['_as'] : $name;
$val = $this->_checkFields($name, $val);
foreach ($fields as $key => $field) {
if (false !== $_field = array_search($field, $val, true)) {
if (is_numeric($_field)) {
$array[] = $k . '.' . $field . ' AS ' . $field;
} elseif ('_' != substr($_field, 0, 1)) {
if (false !== strpos($_field, '*') || false !== strpos($_field, '(') || false !== strpos($_field, '.'))
{
$array[] = $_field . ' AS ' . $field;
} else {
$array[] = $k . '.' . $_field . ' AS ' . $field;
}
}
}
}
}
$fields = implode(',', $array);
}
return $fields;
}
}