追加到Many列表

@param \Imi\Util\ArrayList $manyList
@param array $dataList
@param array $fields
@param string $modelClass
@return void
768373
private static function appendMany($manyList, $dataList, $fields, $modelClass)
    {
        foreach($dataList as $row)
        {
            $tmpRow = [];
            foreach($fields as $alias => $fieldName)
            {
                $tmpRow[$fieldName] = $row[$alias];
            }
            $manyList->append($modelClass::newInstance($tmpRow));
        }
    }
58991
public static function manyToMany($modelClass, $connection, $options = []) {
        $options['type'] = self::MANY_TO_MANY;
        $options['modelClass'] = $modelClass;
        $connection = explode('(', $connection);
        $table = $connection[0];
        list($c1, $c2) = explode(',', $connection[1]);
        $r = new self($options);
        $c1 = trim($c1);
        $c2 = trim($c2);
        $r->join(trim($table), [["t.__PK__", "j.$c1", "="]])
            ->compare(["j.$c2" => "r." . $modelClass::getDb()->getTablePk($modelClass::getTableName())]);
        return $r;
    }
247464
protected function findModel($modelClass, $attributes = [])
    {
        $query = $this->buildQuery($modelClass, $attributes);

        return $query->first();
    }
932622
public function updateCMSFields(FieldList $fields)
    {
        $gridField = GridField::create(
            'CarouselItems',
            _t(__CLASS__ . 'TITLE', 'Hero/Carousel'),
            $this->getCarouselItems(),
            GridFieldConfig_RelationEditor::create()
        );
        $gridField->setDescription(_t(
            __CLASS__ . 'NOTE',
            'NOTE: Carousel functionality will automatically be loaded when 2 or more items are added below'
        ));
        $gridConfig = $gridField->getConfig();
        $gridConfig->getComponentByType(GridFieldAddNewButton::class)->setButtonName(
            _t(__CLASS__ . 'ADDNEW', 'Add new')
        );
        $gridConfig->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
        $gridConfig->removeComponentsByType(GridFieldDeleteAction::class);
        $gridConfig->addComponent(new GridFieldDeleteAction());
        $gridConfig->addComponent(new GridFieldOrderableRows('SortOrder'));
        $gridConfig->removeComponentsByType(GridFieldSortableHeader::class);
        $gridField->setModelClass(CarouselItem::class);

        $fields->findOrMakeTab(
            'Root.Carousel',
            _t(__CLASS__ . 'TITLE', 'Hero/Carousel')
        );

        $fields->addFieldToTab('Root.Carousel', $gridField);
    }
920089
public function isAllowedField($modelClass, $fieldName, $privilege = null)
    {
        return $this->isAllowed($this->fieldResourceGenerator($modelClass, $fieldName), $privilege);
    }
1043548
public function setTables($entityTables, $manyToManyTables)
    {
        $this->tables = $this->manyToManyTables = $this->classToTableNames = [];

        foreach ($entityTables as $table) {
            $className = $this->getClassNameForTable($table->getName());

            $this->classToTableNames[$className] = $table->getName();
            $this->tables[$table->getName()]     = $table;
        }

        foreach ($manyToManyTables as $table) {
            $this->manyToManyTables[$table->getName()] = $table;
        }
    }
1231764
public function addMapping($contentType, $dataClass) {
        if ( ! class_exists($dataClass)
            || ! array_contains(class_implements($dataClass), IHttpData::class)) {
            throw new InvalidDataClassException(
                s('Class "%s" must implement the "%s" interface.',
                    $dataClass, IHttpData::class)
            );
        }

        $this->mappings[$contentType] = $dataClass;
    }
720913
public function getSortTable(DataList $list)
    {
        $field = $this->getSortField();

        if ($list instanceof ManyManyList) {
            $extra = $list->getExtraFields();
            $table = $list->getJoinTable();

            if ($extra && array_key_exists($field, $extra)) {
                return $table;
            }
        }

        $classes = ClassInfo::dataClassesFor($list->dataClass());

        foreach ($classes as $class) {
            if (singleton($class)->hasOwnTableDatabaseField($field)) {
                return $class;
            }
        }

        throw new Exception("Couldn't find the sort field '$field'");
    }
181258
@Override
    public void add(final int arg0, final Object arg1)
    {
        eagerlyLoadDataCollection();

        List dataList = (List) dataCollection;
        if(dataList == null)
        {
            dataList = new ArrayList();
        }

        if (arg1 != null && !dataList.contains(arg1))
        {            
            dataList.add(arg0, arg1);
        }
    }
408719
public function updateCMSFields(FieldList $fields)
    {
        // Update Field Objects (from parent):
        
        parent::updateCMSFields($fields);
        
        // Create Style Fields:
        
        $fields->addFieldsToTab(
            'Root.Style',
            [
                FieldSection::create(
                    'LinkColorStyle',
                    $this->owner->fieldLabel('LinkColorStyle'),
                    [
                        FieldGroup::create(
                            $this->owner->fieldLabel('Background'),
                            [
                                ColorField::create(
                                    'ColorBackgroundLink',
                                    $this->owner->fieldLabel('Link')
                                ),
                                ColorField::create(
                                    'ColorBackgroundHover',
                                    $this->owner->fieldLabel('Hover')
                                ),
                                ColorField::create(
                                    'ColorBackgroundActive',
                                    $this->owner->fieldLabel('Active')
                                )
                            ]
                        ),
                        FieldGroup::create(
                            $this->owner->fieldLabel('Foreground'),
                            [
                                ColorField::create(
                                    'ColorForegroundLink',
                                    $this->owner->fieldLabel('Link')
                                ),
                                ColorField::create(
                                    'ColorForegroundHover',
                                    $this->owner->fieldLabel('Hover')
                                ),
                                ColorField::create(
                                    'ColorForegroundActive',
                                    $this->owner->fieldLabel('Active')
                                )
                            ]
                        )
                    ]
                )
            ]
        );
    }
658839
public function relatedToOne(
        string $otherClass,
        array $fieldsMap,
        bool $applySetters = false
    ) {
        //@TODO remove duplicated code

        $thisValues = array_intersect_key($this->data, $fieldsMap);

        $filterFn = function (Query $query) use (&$thisValues, &$fieldsMap) {
            $query->where(function (WhereClause $where) use (&$query, &$thisValues, &$fieldsMap) {
                foreach ($fieldsMap as $thisKey => $thatKey) {
                    $where->and($thatKey, '=', '?');
                    $query->bind($thisValues[$thisKey]);
                }
            });

            $query->limit(1);
        };

        /* @var $otherClass Model */
        $search = $otherClass::find($filterFn, $applySetters);

        return !(empty($search)) ? $search[0] : null;
    }
297916
public function addCachedField($arFieldList)
    {
        if (empty($arFieldList)) {
            return;
        }

        if (empty($this->cached) || !is_array($this->cached)) {
            $this->cached = [];
        }

        if (is_string($arFieldList)) {
            $arFieldList = [$arFieldList];
        }

        $this->cached = array_merge($this->cached, $arFieldList);
        $this->cached = array_unique($this->cached);
    }
792250
public function setModel($modelClass) {
		$reflection = new ReflectionClass($modelClass);
		if (! $reflection->implementsInterface('ZExt\Model\ModelInterface')) {
			throw new Exception('Class of a model must implements "ModelInterface"');
		}
		
		$this->_modelClass = $modelClass;
		
		if (! empty($this->_models)) {
			$currentModels = $this->_models;
			$this->_models = [];

			foreach ($currentModels as $key => $model) {
				if ($model instanceof $modelClass) {
					$this->_models[$key] = $model;
				} else {
					$model->uninitialize();
				}
			}
		}
				
		return $this;
	}
492205
private function fetchResourceCollection(QueryBuilder $builder, string $modelClass): array
    {
        $statement = $builder->execute();

        $models           = [];
        $counter          = 0;
        $hasMoreThanLimit = false;
        $limit            = $builder->getMaxResults() !== null ? $builder->getMaxResults() - 1 : null;

        if ($this->isFetchTyped() === true) {
            $platform  = $builder->getConnection()->getDatabasePlatform();
            $typeNames = $this->getModelSchemas()->getAttributeTypes($modelClass);
            $statement->setFetchMode(PDOConnection::FETCH_ASSOC);
            while (($attributes = $statement->fetch()) !== false) {
                $counter++;
                if ($limit !== null && $counter > $limit) {
                    $hasMoreThanLimit = true;
                    break;
                }
                $models[] = $this->readResourceFromAssoc($modelClass, $attributes, $typeNames, $platform);
            }
        } else {
            $statement->setFetchMode(PDOConnection::FETCH_CLASS, $modelClass);
            while (($fetched = $statement->fetch()) !== false) {
                $counter++;
                if ($limit !== null && $counter > $limit) {
                    $hasMoreThanLimit = true;
                    break;
                }
                $models[] = $fetched;
            }
        }

        return [$models, $hasMoreThanLimit, $limit, $builder->getFirstResult()];
    }
882921
public static function createFromModelData(array $modelData, string $table, string $field = null)
    {
        $dc = new static($table);

        $dc->strTable = $table;
        $dc->activeRecord = null;

        if (isset($modelData['id']) && $modelData['id'] > 0) {
            $dc->activeRecord = System::getContainer()->get('huh.utils.model')->findModelInstanceByPk($table, $modelData['id']);
            $dc->intId = $modelData['id'];
        }

        if ($field) {
            $dc->strField = $field;
        }

        return $dc;
    }
142854
protected function fixSortColumn($gridField, SS_List $dataList)
    {
        if ($dataList instanceof UnsavedRelationList) {
            return;
        }

        /** @var SS_List|DataList $list */
        $list = clone $dataList;
        $list = $list->alterDataQuery(function ($query, SS_List $tmplist) {
            /** @var DataQuery $query */
            $query->limit(array());
            return $query;
        });

        $many_many = ($list instanceof ManyManyList || $list instanceof ManyManyThroughList);
        if (!$many_many) {
            $sng = singleton($gridField->getModelClass());
            $fieldType = $sng->config()->db[$this->sortColumn];

            if (!$fieldType || !($fieldType == 'Int' || $fieldType == 'SilverStripe\\ORM\\FieldType\\DBInt' || is_subclass_of($fieldType, 'SilverStripe\\ORM\\FieldType\\DBInt'))) {
                if (is_array($fieldType)) {
                    user_error('Sort column ' . $this->sortColumn . ' could not be found in ' . $gridField->getModelClass() . '\'s ancestry', E_USER_ERROR);
                } else {
                    user_error('Sort column ' . $this->sortColumn . ' must be an instance of SilverStripe\\ORM\\FieldType\\DBInt, column is of type ' . $fieldType, E_USER_ERROR);
                }

                exit;
            }
        }

        $max = $list->Max($this->sortColumn);
        $list = $list->filter($this->sortColumn, 0)->sort("Created,ID");
        if ($list->Count() > 0) {
            $owner = $gridField->getForm()->getRecord();
            $sortColumn = $this->sortColumn;
            $i = 1;

            if ($many_many) {
                $schema=Injector::inst()->get(DataObjectSchema::class);
                $componentDetails=$schema->manyManyComponent(get_class($owner), (!empty($this->custom_relation_name) ? $this->custom_relation_name : $gridField->getName()));
                $parentField=$componentDetails['parentField'];
                $componentField=$componentDetails['childField'];
                $table=$componentDetails['join'];
                
                //For ManyManyThroughLists get the right join table
                if ($list instanceof ManyManyThroughList && class_exists($table)) {
                    $table=$schema->tableName($table);
                }

                $extraFields = $list->getExtraFields();

                if (!$extraFields || !array_key_exists($this->sortColumn, $extraFields) || !($extraFields[$this->sortColumn] == 'Int' || $extraFields[$this->sortColumn] == 'SilverStripe\\ORM\\FieldType\\DBInt' || is_subclass_of('SilverStripe\\ORM\\FieldType\\DBInt', $extraFields[$this->sortColumn]))) {
                    user_error('Sort column ' . $this->sortColumn . ' must be an SilverStripe\\ORM\\FieldType\\DBInt, column is of type ' . $extraFields[$this->sortColumn], E_USER_ERROR);
                    exit;
                }
            } else {
                //Find table containing the sort column
                $table = false;
                $class = $gridField->getModelClass();

                $db = Config::inst()->get($class, "db", CONFIG::UNINHERITED);
                if (!empty($db) && array_key_exists($sortColumn, $db)) {
                    $table = DataObject::getSchema()->tableName($class);
                } else {
                    $classes = ClassInfo::ancestry($class, true);
                    foreach ($classes as $class) {
                        $db = Config::inst()->get($class, "db", CONFIG::UNINHERITED);
                        if (!empty($db) && array_key_exists($sortColumn, $db)) {
                            $table = DataObject::getSchema()->tableName($class);
                            break;
                        }
                    }
                }

                if ($table === false) {
                    user_error('Sort column ' . $this->sortColumn . ' could not be found in ' . $gridField->getModelClass() . '\'s ancestry', E_USER_ERROR);
                    exit;
                }

                $baseDataClass = DataObject::getSchema()->baseDataClass($gridField->getModelClass());
                $baseDataTable = DataObject::getSchema()->tableName($baseDataClass);
            }


            //Start transaction if supported
            if (DB::get_conn()->supportsTransactions()) {
                DB::get_conn()->transactionStart();
            }

            $idCondition = null;
            if ($this->append_to_top && !($list instanceof RelationList)) {
                $idCondition = '"ID" IN(\'' . implode("','", $dataList->getIDList()) . '\')';
            }

            if ($this->append_to_top) {
                $topIncremented = array();
            }

            $modelClass = $gridField->getModelClass();
            $hasVersioned = $this->hasVersionedExtension($modelClass);
            foreach ($list as $obj) {
                if ($many_many) {
                    if ($this->append_to_top) {
                        //Upgrade all the records (including the last inserted from 0 to 1)
                        DB::query('UPDATE "' . $table
                            . '" SET "' . $sortColumn . '" = "' . $sortColumn . '"+1'
                            . ' WHERE "' . $parentField . '" = ' . $owner->ID . (!empty($topIncremented) ? ' AND "' . $componentField . '" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));

                        $topIncremented[] = $obj->ID;
                    } else {
                        //Append the last record to the bottom
                        DB::query('UPDATE "' . $table
                            . '" SET "' . $sortColumn . '" = ' . ($max + $i)
                            . ' WHERE "' . $componentField . '" = ' . $obj->ID . ' AND "' . $parentField . '" = ' . $owner->ID);
                    }
                } else if ($this->append_to_top) {
                    if ($hasVersioned) {
                        // For versioned objects, modify them with the ORM so that the *_versions table is updated
                        $itemsToUpdate = $modelClass::get()->where(($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
                        if ($itemsToUpdate->exists()) {
                            foreach ($itemsToUpdate as $item) {
                                $item->$sortColumn = $item->$sortColumn + 1;
                                $item->write();
                            }
                        }
                    }else {
                        //Upgrade all the records (including the last inserted from 0 to 1)
                        DB::query('UPDATE "' . $table
                            . '" SET "' . $sortColumn . '" = "' . $sortColumn . '"+1'
                            . ' WHERE ' . ($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
                    }

                    if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass())) {
                        DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage
                            . '" SET "' . $sortColumn . '" = "' . $sortColumn . '"+1'
                            . ' WHERE ' . ($list instanceof RelationList ? '"' . $list->foreignKey . '" = ' . $owner->ID : $idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\'' . implode('\',\'', $topIncremented) . '\')' : ''));
                    }

                    $topIncremented[] = $obj->ID;
                } else {
                    if ($hasVersioned) {
                        // For versioned objects, modify them with the ORM so that the *_versions table is updated
                        $obj->$sortColumn = ($max + $i);
                        $obj->write();
                    } else {
                        //Append the last record to the bottom
                        DB::query('UPDATE "' . $table
                            . '" SET "' . $sortColumn . '" = ' . ($max + $i)
                            . ' WHERE "ID" = ' . $obj->ID);

                        //LastEdited
                        DB::query('UPDATE "' . $baseDataTable
                            . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
                            . ' WHERE "ID" = ' . $obj->ID);
                    }

                    if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass())) {
                        DB::query('UPDATE "' . $table . '_' . $this->update_versioned_stage
                            . '" SET "' . $sortColumn . '" = ' . ($max + $i)
                            . ' WHERE "ID" = ' . $obj->ID);

                        if ($this->hasVersionedExtension($baseDataClass)) {
                            DB::query('UPDATE "' . $baseDataTable . '_' . $this->update_versioned_stage
                                . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
                                . ' WHERE "ID" = ' . $obj->ID);
                        }
                    }
                }

                $i++;
            }

            //Update LastEdited for affected records when using append to top on a many_many relationship
            if (!$many_many && $this->append_to_top && count($topIncremented) > 0) {
                DB::query('UPDATE "' . $baseDataTable
                    . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
                    . ' WHERE "ID" IN(\'' . implode('\',\'', $topIncremented) . '\')');

                if ($this->update_versioned_stage && $this->hasVersionedExtension($gridField->getModelClass()) && $this->hasVersionedExtension($baseDataClass)) {
                    DB::query('UPDATE "' . $baseDataTable . '_' . $this->update_versioned_stage
                        . '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
                        . ' WHERE "ID" IN(\'' . implode('\',\'', $topIncremented) . '\')');
                }
            }


            //End transaction if supported
            if (DB::get_conn()->supportsTransactions()) {
                DB::get_conn()->transactionEnd();
            }
        }
    }
280156
public function initAction(Model $m, $fields = null)
    {
        $keys = $fields ? array_flip($fields) : null;

        $data = array_map(function ($r) use ($m, $keys) {
            return $this->typecastLoadRow($m, $keys ? array_intersect_key($r, $keys) : $r);
        }, $this->data[$m->table]);

        return new \atk4\data\Action\Iterator($data);
    }