⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.inc.php.svn-base

📁 PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
	        	if ($this->isDBonly() || $this->isTextOnly())        		{					$this->clearPoint();					$point = 'point';        		}        	}        }        if ($point == 'point')        {			if ($this->isDBandText())			{				$point = 'merge';				$left->setPoint('point');				$right->setPoint('point');			}        }        if (is_null($point) && !DefaultOpCollection::isBoolean($op))        {        	$point = 'point';        }		$this->setPoint($point);    }    private function isDBonly()    {    	return $this->getHasDb() && !$this->getHasText();    }    private function isTextOnly()    {    	return !$this->getHasDb() && $this->getHasText();    }    private function isDBandText()    {    	return $this->getHasDb() && $this->getHasText();    }    public function appliesToContext()    {        return $this->left()->appliesToContext() | $this->right()->appliesToContext();    }    /**     * Enter description here...     *     * @param OpExpr $expr     */    protected  function clearPoint()    {    	if (DefaultOpCollection::isBoolean($this))    	{			$this->left()->clearPoint();			$this->right()->clearPoint();    	}    	if ($this->isMergePoint())    	{    		$this->setPoint(null);    	}    }    protected function isMergePoint()    {    	return in_array($this->getPoint(), array('merge','point'));    }    /**     * Returns the operator on the expression     *     * @return ExprOp     */    public function op()    {        return $this->op;    }    /**     * Returns true if the negative of the operator should be used in evaluation     *     * @param boolean $not     * @return boolean     */    public function not($not=null)    {        if (!is_null($not))        {            $this->not = $not;        }        return $this->not;    }    /**     * The left side of the  expression     *     * @return Expr     */    public function &left()    {        return $this->left_expr;    }    /**     * The right side of the  expression     *     * @return Expr     */    public function &right()    {        return $this->right_expr;    }    /**     * Converts the expression to a string     *     * @return string     */    public function __toString()    {        // _kt may not translate well here.        $expr = $this->left_expr . ' ' . _kt($this->op) .' ' .  $this->right_expr;        if (is_null($this->parent))        {        	if ($this->not())        	{            	 $expr = _kt('NOT') . $expr;        	}            return $expr;        }        if ($this->parent->isOpExpr())        {            if ($this->parent->op != $this->op && in_array($this->op, DefaultOpCollection::$boolean))            {                 $expr = "($expr)";            }        }        if ($this->not())        {             $expr = "!($expr)";        }        return $expr;    }    /**     * Is the expression valid     *     * @return boolean     */    public function is_valid()    {        $left = $this->left();        $right = $this->right();        return $left->is_valid() && $right->is_valid();    }    /**     * Finds the results that are in both record sets.     *     * @param array $leftres     * @param array $rightres     * @return array     */	protected static function _intersect($leftres, $rightres)    {    	if (empty($leftres) || empty($rightres))    	{    		return array(); // small optimisation    	}    	$result = array();    	foreach($leftres as $item)    	{    		$document_id = $item->Id;    		if (!$item->IsLive)    		{    			continue;    		}    		if (array_key_exists($document_id, $rightres))    		{    			$check = $rightres[$document_id];    			$result[$document_id] = ($item->Rank < $check->Rank)?$check:$item;    		}    	}    	return $result;    }	protected static function intersect($leftres, $rightres)    {        return array(            'docs'=>self::_intersect($leftres['docs'],$rightres['docs']),            'folders'=>self::_intersect($leftres['folders'],$rightres['folders'])        );    }	protected static function union($leftres, $rightres)    {        return array(            'docs'=>self::_union($leftres['docs'],$rightres['docs']),            'folders'=>self::_union($leftres['folders'],$rightres['folders'])        );    }    /**     * The objective of this function is to merge the results so that there is a union of the results,     * but there should be no duplicates.     *     * @param array $leftres     * @param array $rightres     * @return array     */    protected static function _union($leftres, $rightres)    {    	if (empty($leftres))    	{    		return $rightres; // small optimisation    	}    	if (empty($rightres))    	{    		return $leftres; // small optimisation    	}    	$result = array();    	foreach($leftres as $item)    	{			if ($item->IsLive)    		{    			$result[$item->Id] = $item;    		}    	}    	foreach($rightres as $item)    	{    		if (!array_key_exists($item->Id, $result) || $item->Rank > $result[$item->Id]->Rank)    		{    			$result[$item->Id] = $item;    		}    	}    	return $result;    }    /**     * Enter description here...     *     * @param OpExpr $left     * @param ExprOp $op     * @param OpExpr $right     * @param boolean $not     */    public function transform(& $left, & $op, & $right, & $not)    {    	if (!$left->isOpExpr() || !$right->isOpExpr() || !DefaultOpCollection::isBoolean($op))    	{    		return;    	}		if ($left->isTextOnly() && $right->isDBonly())		{			// we just swap the items around, to ease other transformations			$tmp = $left;			$left = $right;			$right = $tmp;			return;		}		if ($op != $right->op() || !DefaultOpCollection::isBoolean($right))		{			return;		}		if ($op == ExprOp::OP_OR && ($not || $right->not()))		{			// NOTE: we can't transform. e.g.			// db or !(db or txt) => db or !db and !txt			// so nothing to do			// BUT: db and !(db and txt) => db and !db and !txt			return;		}		$rightLeft = $right->left();		$rightRight = $right->right();		if ($left->isDBonly() && $rightLeft->isDBonly())		{			$newLeft = new OpExpr( $left, $op, $rightLeft );			$right = $rightRight;			$left = $newLeft;			return;		}		if ($left->isTextOnly() && $rightRight->isTextOnly())		{			$newRight = new OpExpr($left, $op, $rightRight);			$left = $rightLeft;			$right = $newRight;			return;		}    }    private function findDBNode($start, $op, $what)    {    	if ($start->op() != $op)    	{    		return null;    	}    	switch($what)    	{    		case 'db':    			if ($start->isDBonly())    			{    				return $start;    			}    			break;    		case 'txt':    			if ($start->isTextOnly())    			{    				return $start;    			}    			break;    	}    	$node = $this->findDBNode($start->left(), $op, $what);    	if (is_null($left))    	{    		$node = $this->findDBNode($start->right(), $op, $what);    	}    	return $node;    }    public function traverse($object, $method, $param)    {    	if ($this->isOpExpr())    	{	    	$object->$method($param);    	}    }    private function exploreItem($item, & $group, $interest)    {    	if (($interest == 'db' && $item->getHasDb()) ||    		($interest == 'text' && $item->getHasText()))    	{			if (in_array($item->op(), array(ExprOp::OP_OR, ExprOp::OP_AND)))			{				$this->exploreItem($item->left(),  $group, $interest);				$this->exploreItem($item->right(),  $group, $interest);			}			else			{				$group[] = $item;			}    	}    }    private function explore($left, $right, & $group, $interest)    {		$this->exploreItem($left,  $group, $interest);		$this->exploreItem($right,  $group, $interest);    }    private function exec_db_query($op, $group)    {    	if (empty($group)) { return array(); }    	$exprbuilder = new SQLQueryBuilder($this->getContext());    	if (count($group) == 1)    	{    		$sql = $exprbuilder->buildComplexQuery($group[0]);    	}    	else    	{			$sql = $exprbuilder->buildSimpleQuery($op, $group);    	}    	if (empty($sql))    	{    	    return array();    	}    	$results = array();    	global $default;    	$default->log->debug("SEARCH SQL: $sql");    	$rs = DBUtil::getResultArray($sql);    	if (PEAR::isError($rs))    	{    		throw new Exception($rs->getMessage());    	}    	foreach($rs as $item)    	{    		$id = $item['id'];    		$rank = $exprbuilder->getRanking($item);    		if (!array_key_exists($id, $results) || $rank > $results[$id]->Rank)    		{    		    if ($this->context == ExprContext::DOCUMENT)    		    {    		        $results[$id] = new DocumentResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item));    		    }    		    else    		    {    		        $results[$id] = new FolderResultItem($id, $rank, $item['title'], $exprbuilder->getResultText($item));    		    }    		}    	}    	return $results;    }    private function exec_text_query($op, $group)    {        if (($this->getContext() != ExprContext::DOCUMENT) || empty($group))        {            return array();        }    	$exprbuilder = new TextQueryBuilder();    	if (count($group) == 1)    	{    		$query = $exprbuilder->buildComplexQuery($group[0]);    	}    	else    	{			$query = $exprbuilder->buildSimpleQuery($op, $group);    	}    	if (empty($query))    	{    	    return array();    	}    	$indexer = Indexer::get();    	global $default;    	$default->log->debug("SEARCH LUCENE: $query");    	$results = $indexer->query($query);    	foreach($results as $item)    	{    		$item->Rank = $exprbuilder->getRanking($item);    		$exprbuilder->setQuery($query);    		//$item->Text = $exprbuilder->getResultText($item); ?? wipe - done at indexer level    	}    	return $results;    }	public function evaluate($context = ExprContext::DOCUMENT_AND_FOLDER)	{	    if ($context == ExprContext::DOCUMENT_AND_FOLDER)	    {	       $docs = $this->evaluate(ExprContext::DOCUMENT); 	       $folders = $this->evaluate(ExprContext::FOLDER);	       return array(	           'docs' => $docs['docs'],	           'folders' => $folders['folders']);	    }	    $this->setContext($context);		$left = $this->left();        $right = $this->right();        $op = $this->op();        $point = $this->getPoint();        $result = array();        if (empty($point))        {        	$point = 'point';        }		$resultContext = ($this->getContext() == ExprContext::DOCUMENT)?'docs':'folders';		if ($point == 'merge')		{			$leftres = $left->evaluate($context);			$rightres = $right->evaluate($context);			switch ($op)			{				case ExprOp::OP_AND:					if ($this->debug) print "\n\nmerge: intersect\n\n";					$result = OpExpr::intersect($leftres, $rightres);					break;				case ExprOp::OP_OR:					if ($this->debug) print "\n\nmerge: union\n\n";					$result = OpExpr::union($leftres, $rightres);					break;				default:					throw new Exception("this condition should not happen");			}		}		elseif ($point == 'point')		{			if ($this->isDBonly())			{				$result[$resultContext] = $this->exec_db_query($op, array($this));			}			elseif ($this->isTextOnly())			{				$result[$resultContext] = $this->exec_text_query($op, array($this));			}			elseif (in_array($op, array(ExprOp::OP_OR, ExprOp::OP_AND)))			{			    // do we get to this???			    // TODO: remove me please.... the simpleQuery stuff should go???				$db_group = array();				$text_group = array();				$this->explore($left, $right, $db_group, 'db');				$this->explore($left, $right, $text_group, 'text');				$db_result[$resultContext] = $this->exec_db_query($op, $db_group);				$text_result[$resultContext] = $this->exec_text_query($op, $text_group);				switch ($op)				{					case ExprOp::OP_AND:						if ($this->debug) print "\n\npoint: intersect\n\n";						$result[$resultContext] = OpExpr::intersect($db_result, $text_result);						break;					case ExprOp::OP_OR:						if ($this->debug) print "\n\nmerge: union\n\n";						$result[$resultContext] = OpExpr::union($db_result, $text_result);						break;					default:						throw new Exception('how did this happen??');				}			}			else			{				throw new Exception('and this?');			}		}		else		{			// we don't have to do anything			//throw new Exception('Is this reached ever?');		}		$permResults = array();		foreach($result[$resultContext] as $idx=>$item)		{			$permResults[$resultContext][$idx] = $item;		}		return $permResults;	}    public function toViz(&$str, $phase)    {        $expr_id = $this->getExprId();        $left = $this->left();        $right = $this->right();        $hastext = $this->getHasText()?'TEXT':'';        $hasdb = $this->getHasDb()?'DB':'';        switch ($phase)        {            case 0:                $not = $this->not()?'NOT':'';                $str .= "struct$expr_id [style=box, label=\"$expr_id: $not $this->op $this->point $hastext$hasdb\"]\n";                break;            case 1:                $left_id = $left->getExprId();                $str .= "struct$expr_id -> struct$left_id\n";                $right_id = $right->getExprId();                $str .= "struct$expr_id -> struct$right_id\n";                break;        }        $left->toViz($str, $phase);        $right->toViz($str, $phase);    }}?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -