Вход Регистрация
Файл: src/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php
Строк: 222
<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the MIT license. For more information, see
 * <http://www.doctrine-project.org>.
 */

namespace DoctrineCommonCollectionsExpr;

/**
 * Walks an expression graph and turns it into a PHP closure.
 *
 * This closure can be used with {@Collection#filter()} and is used internally
 * by {@ArrayCollection#select()}.
 *
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 * @since  2.3
 */
class ClosureExpressionVisitor extends ExpressionVisitor
{
    
/**
     * Accesses the field of a given object. This field has to be public
     * directly or indirectly (through an accessor get*, is*, or a magic
     * method, __get, __call).
     *
     * @param object $object
     * @param string $field
     *
     * @return mixed
     */
    
public static function getObjectFieldValue($object$field)
    {
        if (
is_array($object)) {
            return 
$object[$field];
        }

        
$accessors = array('get''is');

        foreach (
$accessors as $accessor) {
            
$accessor .= $field;

            if ( ! 
method_exists($object$accessor)) {
                continue;
            }

            return 
$object->$accessor();
        }

        
// __call should be triggered for get.
        
$accessor $accessors[0] . $field;

        if (
method_exists($object'__call')) {
            return 
$object->$accessor();
        }

        if (
$object instanceof ArrayAccess) {
            return 
$object[$field];
        }

        return 
$object->$field;
    }

    
/**
     * Helper for sorting arrays of objects based on multiple fields + orientations.
     *
     * @param string   $name
     * @param int      $orientation
     * @param Closure $next
     *
     * @return Closure
     */
    
public static function sortByField($name$orientation 1Closure $next null)
    {
        if ( ! 
$next) {
            
$next = function() {
                return 
0;
            };
        }

        return function (
$a$b) use ($name$next$orientation) {
            
$aValue ClosureExpressionVisitor::getObjectFieldValue($a$name);
            
$bValue ClosureExpressionVisitor::getObjectFieldValue($b$name);

            if (
$aValue === $bValue) {
                return 
$next($a$b);
            }

            return ((
$aValue $bValue) ? : -1) * $orientation;
        };
    }

    
/**
     * {@inheritDoc}
     */
    
public function walkComparison(Comparison $comparison)
    {
        
$field $comparison->getField();
        
$value $comparison->getValue()->getValue(); // shortcut for walkValue()

        
switch ($comparison->getOperator()) {
            case 
Comparison::EQ:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) === $value;
                };

            case 
Comparison::NEQ:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) !== $value;
                };

            case 
Comparison::LT:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) < $value;
                };

            case 
Comparison::LTE:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) <= $value;
                };

            case 
Comparison::GT:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) > $value;
                };

            case 
Comparison::GTE:
                return function (
$object) use ($field$value) {
                    return 
ClosureExpressionVisitor::getObjectFieldValue($object$field) >= $value;
                };

            case 
Comparison::IN:
                return function (
$object) use ($field$value) {
                    return 
in_array(ClosureExpressionVisitor::getObjectFieldValue($object$field), $value);
                };

            case 
Comparison::NIN:
                return function (
$object) use ($field$value) {
                    return ! 
in_array(ClosureExpressionVisitor::getObjectFieldValue($object$field), $value);
                };

            case 
Comparison::CONTAINS:
                return function (
$object) use ($field$value) {
                    return 
false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object$field), $value);
                };

            default:
                throw new 
RuntimeException("Unknown comparison operator: " $comparison->getOperator());
        }
    }

    
/**
     * {@inheritDoc}
     */
    
public function walkValue(Value $value)
    {
        return 
$value->getValue();
    }

    
/**
     * {@inheritDoc}
     */
    
public function walkCompositeExpression(CompositeExpression $expr)
    {
        
$expressionList = array();

        foreach (
$expr->getExpressionList() as $child) {
            
$expressionList[] = $this->dispatch($child);
        }

        switch(
$expr->getType()) {
            case 
CompositeExpression::TYPE_AND:
                return 
$this->andExpressions($expressionList);

            case 
CompositeExpression::TYPE_OR:
                return 
$this->orExpressions($expressionList);

            default:
                throw new 
RuntimeException("Unknown composite " $expr->getType());
        }
    }

    
/**
     * @param array $expressions
     *
     * @return callable
     */
    
private function andExpressions($expressions)
    {
        return function (
$object) use ($expressions) {
            foreach (
$expressions as $expression) {
                if ( ! 
$expression($object)) {
                    return 
false;
                }
            }
            return 
true;
        };
    }

    
/**
     * @param array $expressions
     *
     * @return callable
     */
    
private function orExpressions($expressions)
    {
        return function (
$object) use ($expressions) {
            foreach (
$expressions as $expression) {
                if (
$expression($object)) {
                    return 
true;
                }
            }
            return 
false;
        };
    }
}
Онлайн: 0
Реклама