📄 expr.inc.php.svn-base
字号:
return ''; } $sql = 'SELECT ' . "\n"; if ($this->context == ExprContext::DOCUMENT) { // we are doing this because content table is dependant on metadata table if ($this->used_tables['document_content_version'] > 0) { $this->used_tables['document_metadata_version']++; } $sql .= ' DISTINCT d.id, dmv.name as title'; } else { $sql .= ' DISTINCT f.id, f.name as title'; } $offset=0; foreach($this->db as $expr) { $offset++; $sql .= ", ifnull(" . $this->getSQLEvalExpr($expr) . ",0) as expr$offset "; } foreach($this->metadata as $expr) { $offset++; $sql .= ", ifnull(" . $this->getSQLEvalExpr($expr) . ",0) as expr$offset "; } $sql .= "\n" . 'FROM ' ."\n"; if ($this->context == ExprContext::DOCUMENT) { $primaryAlias = 'd'; $sql .= ' documents d ' ."\n"; if ($this->used_tables['document_metadata_version'] > 0) { $sql .= ' INNER JOIN document_metadata_version dmv ON d.metadata_version_id=dmv.id' . "\n"; } if ($this->used_tables['document_content_version'] > 0) { $sql .= ' INNER JOIN document_content_version dcv ON dmv.content_version_id=dcv.id ' . "\n"; } if ($this->used_tables['document_fields_link'] > 0) { $sql .= ' LEFT JOIN document_fields_link pdfl ON dmv.id=pdfl.metadata_version_id ' . "\n"; } if ($this->used_tables['tag_words'] > 0) { $sql .= ' LEFT OUTER JOIN document_tags dt ON dt.document_id=d.id ' . "\n" . ' LEFT OUTER JOIN tag_words tw ON dt.tag_id = tw.id ' . "\n"; } } else { $primaryAlias = 'f'; $sql .= ' folders f ' ."\n"; } $offset = 0; foreach($this->db as $expr) { $field = $expr->left(); $jointable=$field->getJoinTable(); if (!is_null($jointable)) { $fieldname = $this->resolveTableToAlias($field->getTable()) . '.' . $field->getField(); $joinalias = "$jointable$offset"; $joinfield = $field->getJoinField(); $sql .= " LEFT OUTER JOIN $jointable $joinalias ON $fieldname=$joinalias.$joinfield\n"; } $offset++; } if ($this->context == ExprContext::DOCUMENT) { $offset=0; foreach($this->metadata as $expr) { $offset++; $field = $expr->left(); $fieldid = $field->getFieldId(); $sql .= " LEFT JOIN document_fields_link dfl$offset ON dfl$offset.metadata_version_id=d.metadata_version_id AND dfl$offset.document_field_id=$fieldid" . "\n"; $sql .= " LEFT JOIN document_fields df$offset ON df$offset.id=dfl$offset.document_field_id" . "\n"; } } // Add permissions sql for read access $oPermission =& KTPermission::getByName('ktcore.permissions.read'); $permId = $oPermission->getID(); $oUser = User::get($_SESSION['userID']); $aPermissionDescriptors = KTPermissionUtil::getPermissionDescriptorsForUser($oUser); $sPermissionDescriptors = empty($aPermissionDescriptors)? -1: implode(',', $aPermissionDescriptors); $sql .= "INNER JOIN permission_lookups AS PL ON $primaryAlias.permission_lookup_id = PL.id\n"; $sql .= 'INNER JOIN permission_lookup_assignments AS PLA ON PL.id = PLA.permission_lookup_id AND PLA.permission_id = '.$permId. " \n"; $sql .= "WHERE PLA.permission_descriptor_id IN ($sPermissionDescriptors) AND "; if ($this->context == ExprContext::DOCUMENT) { $sql .= "dmv.status_id=1 AND d.status_id=1 AND d.linked_document_id is null"; } else { $sql .= "f.linked_folder_id is null"; } $sql .= ' AND '; return $sql; } private function resolveMetadataOffset($expr) { if (!$expr->left()->isMetadataField()) { throw new Exception(_kt('Metadata field expected')); } $offset=0; foreach($this->metadata as $item) { if ($item->getExprId() == $expr->getExprId()) { return $offset; } $offset++; } throw new Exception('metadata field not found'); } private function resolveJoinOffset($expr) { $offset=0; foreach($this->db as $item) { if ($item->getExprId() == $expr->getExprId()) { return $offset; } $offset++; } throw new Exception('join field not found'); } private function buildCoreSQLExpr($expr) { $left = $expr->left(); $right = $expr->right(); if (DefaultOpCollection::isBoolean($expr)) { $query = '(' . $this->buildCoreSQLExpr($left) . ' ' . $expr->op() . ' ' . $this->buildCoreSQLExpr($right) . ')'; } else { if (($this->context & $expr->appliesToContext()) == $this->context) { $query = $this->getSQLEvalExpr($expr); } else { $query = 'false'; } } return $query; } public function buildComplexQuery($expr) {// print "building complex \n\n"; $this->exploreExprs($expr); $sql = $this->buildCoreSQL(); if (empty($sql)) { return ''; } $expr = $this->buildCoreSQLExpr($expr); $sql .= $expr; $config = KTConfig::getSingleton(); $maxSqlResults = $config->get('search/maxSqlResults', 1000); $sql .= "limit $maxSqlResults"; return $sql; } public function buildSimpleQuery($op, $group) {// print "building simple \n\n"; $this->exploreGroup($group); $sql = $this->buildCoreSQL(); $offset=0; foreach($this->db as $expr) { if ($offset++) { $sql .= " $op\n " ; } $field = $expr->left(); if (is_null($field->getJoinTable())) { $alias = $this->resolveTableToAlias($field->getTable()); $fieldname = $alias . '.' . $field->getField(); } else { $offset = $this->resolveJoinOffset($expr); $matching = $field->getMatchingField(); $tablename = $field->getJoinTable(); $fieldname = "$tablename$offset.$matching"; } $value = $expr->right(); $sql .= $value->getSQL($field, $left->modifyName($fieldname), $expr->op(), $expr->not()); } if ($this->context == ExprContext::DOCUMENT) { $moffset=0; foreach($this->metadata as $expr) { $moffset++; if ($offset++) { $sql .= " $op\n " ; } $field = $expr->left(); $value = $expr->right(); $sql .= $value->getSQL($field, "dfl$moffset.value", $expr->getOp()); } } $config = KTConfig::getSingleton(); $maxSqlResults = $config->get('search/maxSqlResults', 1000); $sql .= "limit $maxSqlResults"; return $sql; } public function getRanking($result) { $ranker = RankManager::get(); $score = 0; foreach($result as $col=>$val) { if ($val + 0 == 0) { // we are not interested if the expression failed continue; } if (substr($col, 0, 4) == 'expr' && is_numeric(substr($col, 4))) { $exprno = substr($col, 4); if ($exprno <= count($this->db)) { $expr = $this->db[$exprno-1]; $left=$expr->left(); $score += $ranker->scoreField($left->getTable(), 'T', $left->getField()); } else { $exprno -= count($this->db); $expr = $this->metadata[$exprno-1]; $left=$expr->left(); $score += $ranker->scoreField($left->getTable(), 'M', $left->getField()); } } } return $score; } public function getResultText($result) { $text = array(); foreach($result as $col=>$val) { if (substr($col, 0, 4) == 'expr' && is_numeric(substr($col, 4))) { if ($val + 0 == 0) { // we are not interested if the expression failed continue; } $exprno = substr($col, 4); if ($exprno <= count($this->db)) { $expr = $this->db[$exprno-1]; } else { $exprno -= count($this->db); $expr = $this->metadata[$exprno-1]; } $text[] = (string) $expr; } } return '(' . implode(') AND (', $text) . ')'; }}class OpExpr extends Expr{ /** * The left side of the expression * * @var Expr */ protected $left_expr; /** * The operator on the left and right * * @var ExprOp */ protected $op; /** * The right side of the expression * * @var Expr */ protected $right_expr; /** * This indicates that the expression is negative * * @var boolean */ protected $not; protected $point; protected $has_text; protected $has_db; private $debug = false;// protected $flattened; protected $results; public function setResults($results) { $this->results=$results; } public function getResults() { return $this->results; } public function setHasDb($value=true) { $this->has_db=$value; } public function setHasText($value=true) { $this->has_text=$value; } public function setContext($context) { parent::setContext($context); $this->left()->setContext($context); $this->right()->setContext($context); } public function getHasDb() { return $this->has_db; } public function getHasText() { return $this->has_text; } public function setPoint($point) { $this->point = $point; /* if (!is_null($point)) { $this->flattened = new FlattenedGroup($this); } else { if (!is_null($this->flattened)) { unset($this->flattened); } $this->flattened = null; }*/ } public function getPoint() { return $this->point; } public function hasSameOpAs($expr) { return $this->op() == $expr->op(); } public static function rewriteString(&$left, &$op, &$right, $not=false) { if ($right->isValueExpr()) { $value = $right->getValue(); } else { $value = $right; } $text = array(); preg_match_all('/[\']([^\']*)[\']/',$value, $matches); foreach($matches[0] as $item) { $text [] = $item; $value = str_replace($item, '', $value); } $matches = explode(' ', $value); foreach($matches as $item) { if (empty($item)) continue; $text[] = $item; } if (count($text) == 1) { return; } $doctext = $left; $left = new OpExpr($doctext, $op, new ValueExpr($text[0])); for($i=1;$i<count($text);$i++) { if ($i==1) { $right = new OpExpr($doctext, $op, new ValueExpr($text[$i])); } else { $join = new OpExpr($doctext, $op, new ValueExpr($text[$i])); $right = new OpExpr($join, ExprOp::OP_AND, $right); } } $op = ExprOp::OP_AND; } /** * Constructor for the expression * * @param Expr $left * @param ExprOp $op * @param Expr $right */ public function __construct($left, $op, $right, $not = false) { // if left is a string, we assume we should convert it to a FieldExpr if (is_string($left)) { $left = new $left; } // if right is not an expression, we must convert it! if (!($right instanceof Expr)) { $right = new ValueExpr($right); } if ($right->isValueListExpr()) { $right->rewrite($left, $op, $right, $not); } else // rewriting is based on the FieldExpr, and can expand a simple expression // into something a little bigger. if ($left->isFieldExpr()) { $left->rewrite($left, $op, $right, $not); } // transformation is required to optimise the expression tree so that // the queries on the db and full text search are optimised. if (DefaultOpCollection::isBoolean($op)) { $this->transform($left, $op, $right, $not); } parent::__construct(); $left->setParent($this); $right->setParent($this); $this->left_expr=&$left; $this->op = $op; $this->right_expr=&$right; $this->not = $not; $this->has_text=false; // $this->setPoint('point'); if ($left->isSearchableText()) { $this->setHasText(); } else if ($left->isDBExpr()) { $this->setHasDb(); } elseif ($left->isOpExpr()) { if ($left->getHasText()) { $this->setHasText(); } if ($left->getHasDb()) { $this->setHasDb(); } } if ($right->isOpExpr()) { if ($right->getHasText()) { $this->setHasText(); } if ($right->getHasDb()) { $this->setHasDb(); } } // $this->flattened=null; // $left_op, etc indicates that $left expression is a logical expression $left_op = ($left->isOpExpr() && DefaultOpCollection::isBoolean($left)); $right_op = ($right->isOpExpr() && DefaultOpCollection::isBoolean($right)); // check which trees match $left_op_match = ($left_op && $this->hasSameOpAs($left)) ; $right_op_match = ($right_op && $this->hasSameOpAs($left)) ; $point = null; if ($left_op_match && $right_op_match) { $point = 'point'; } $left_op_match_flex = $left_op_match || ($left->isOpExpr()); $right_op_match_flex = $right_op_match || ($right->isOpExpr()); if ($left_op_match_flex && $right_op_match_flex) { $point = 'point'; } if (!is_null($point)) { if ($left_op_match && $left->getPoint() == 'point') { $left->setPoint(null); } if ($right_op_match && $right->getPoint() == 'point') { $right->setPoint(null); } if ($left->isMergePoint() && is_null($right->getPoint())) { $right->setPoint('point'); } if ($right->isMergePoint() && is_null($left->getPoint())) { $left->setPoint('point'); } if ($left->isMergePoint() || $right->isMergePoint()) { $point = 'merge'; if (!$left->isMergePoint()) { $left->setPoint('point'); } if (!$right->isMergePoint()) { $right->setPoint('point'); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -