Вход Регистрация
Файл: framework/model/PolymorphicHasManyList.php
Строк: 148
<?php

/**
 * Represents a has_many list linked against a polymorphic relationship
 *
 * @package framework
 * @subpackage model
 */
class PolymorphicHasManyList extends HasManyList {

    
/**
     * Name of foreign key field that references the class name of the relation
     *
     * @var string
     */
    
protected $classForeignKey;

    
/**
     * Retrieve the name of the class this relation is filtered by
     *
     * @return string
     */
    
public function getForeignClass() {
        return 
$this->dataQuery->getQueryParam('Foreign.Class');
    }

    
/**
     * Create a new PolymorphicHasManyList relation list.
     *
     * @param string $dataClass The class of the DataObjects that this will list.
     * @param string $foreignField The name of the composite foreign relation field. Used
     * to generate the ID and Class foreign keys.
     * @param string $foreignClass Name of the class filter this relation is filtered against
     */
    
function __construct($dataClass$foreignField$foreignClass) {

        
// Set both id foreign key (as in HasManyList) and the class foreign key
        
parent::__construct($dataClass"{$foreignField}ID");
        
$this->classForeignKey "{$foreignField}Class";

        
// Ensure underlying DataQuery globally references the class filter
        
$this->dataQuery->setQueryParam('Foreign.Class'$foreignClass);

        
// For queries with multiple foreign IDs (such as that generated by
        // DataList::relation) the filter must be generalised to filter by subclasses
        
$classNames Convert::raw2sql(ClassInfo::subclassesFor($foreignClass));
        
$this->dataQuery->where(sprintf(
            
""{$this->classForeignKey}" IN ('%s')",
            
implode("', '"$classNames)
        ));
    }

    
/**
     * Adds the item to this relation.
     *
     * It does so by setting the relationFilters.
     *
     * @param $item The DataObject to be added, or its ID
     */
    
public function add($item) {
        if(
is_numeric($item)) {
            
$item DataObject::get_by_id($this->dataClass$item);
        } else if(!(
$item instanceof $this->dataClass)) {
            
user_error(
                
"PolymorphicHasManyList::add() expecting a $this->dataClass object, or ID value",
                
E_USER_ERROR
            
);
        }

        
$foreignID $this->getForeignID();

        
// Validate foreignID
        
if(!$foreignID) {
            
user_error(
                
"PolymorphicHasManyList::add() can't be called until a foreign ID is set",
                
E_USER_WARNING
            
);
            return;
        }
        if(
is_array($foreignID)) {
            
user_error(
                
"PolymorphicHasManyList::add() can't be called on a list linked to mulitple foreign IDs",
                
E_USER_WARNING
            
);
            return;
        }

        
$foreignKey $this->foreignKey;
        
$classForeignKey $this->classForeignKey;
        
$item->$foreignKey $foreignID;
        
$item->$classForeignKey $this->getForeignClass();

        
$item->write();
    }

    
/**
     * Remove an item from this relation.
     * Doesn't actually remove the item, it just clears the foreign key value.
     *
     * @param $item The DataObject to be removed
     * @todo Maybe we should delete the object instead?
     */
    
public function remove($item) {
        if(!(
$item instanceof $this->dataClass)) {
            throw new 
InvalidArgumentException("HasManyList::remove() expecting a $this->dataClass object, or ID",
                
E_USER_ERROR);
        }

        
// Don't remove item with unrelated class key
        
$foreignClass $this->getForeignClass();
        
$classNames ClassInfo::subclassesFor($foreignClass);
        
$classForeignKey $this->classForeignKey;
        if(!
in_array($item->$classForeignKey$classNames)) return;

        
// Don't remove item which doesn't belong to this list
        
$foreignID $this->getForeignID();
        
$foreignKey $this->foreignKey;

        if(    empty(
$foreignID)
            || (
is_array($foreignID) && in_array($item->$foreignKey$foreignID))
            || 
$foreignID == $item->$foreignKey
        
) {
            
$item->$foreignKey null;
            
$item->$classForeignKey null;
            
$item->write();
        }

    }
}
Онлайн: 0
Реклама