本文整理汇总了PHP中DataObject::database_fields方法的典型用法代码示例。如果您正苦于以下问题:PHP DataObject::database_fields方法的具体用法?PHP DataObject::database_fields怎么用?PHP DataObject::database_fields使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DataObject
的用法示例。
在下文中一共展示了DataObject::database_fields方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: augmentSQL
/**
* @see DataExtension::augmentSQL()
*/
public function augmentSQL(SQLQuery &$query)
{
$select = $query->getSelect();
if (empty($select) || $query->getDelete() || in_array("COUNT(*)", $select) || in_array("count(*)", $select)) {
return;
}
if (!isset(self::$sortTables[$this->owner->class])) {
$classes = array_reverse(ClassInfo::dataClassesFor($this->owner->class));
$class = null;
foreach ($classes as $cls) {
if (DataObject::has_own_table($cls) && ($fields = DataObject::database_fields($cls)) && isset($fields['SortOrder'])) {
$class = $cls;
break;
}
}
self::$sortTables[$this->owner->class] = $class;
} else {
$class = self::$sortTables[$this->owner->class];
}
if ($class) {
$query->addOrderBy("\"{$class}\".\"SortOrder\" " . self::$sort_dir);
} else {
$query->addOrderBy("\"SortOrder\" " . self::$sort_dir);
}
}
示例2: fieldsInExtraTables
/**
* fieldsInExtraTables function.
*
* @access public
* @param mixed $suffix
* @return array
*/
public function fieldsInExtraTables($suffix)
{
$fields = array();
//$fields['db'] = DataObject::database_fields($this->owner->class);
$fields['indexes'] = $this->owner->databaseIndexes();
$fields['db'] = array_merge(DataObject::database_fields($this->owner->class));
return $fields;
}
示例3: allFieldsForClass
public static function allFieldsForClass($class)
{
$dataClasses = ClassInfo::dataClassesFor($class);
$fields = array();
foreach ($dataClasses as $dataClass) {
$fields = array_merge($fields, array_keys(DataObject::database_fields($dataClass)));
}
return array_combine($fields, $fields);
}
示例4: __construct
/**
* Constructor method for MemberTableField.
*
* @param Controller $controller Controller class which created this field
* @param string $name Name of the field (e.g. "Members")
* @param mixed $group Can be the ID of a Group instance, or a Group instance itself
* @param DataObjectSet $members Optional set of Members to set as the source items for this field
* @param boolean $hidePassword Hide the password field or not in the summary?
*/
function __construct($controller, $name, $group = null, $members = null, $hidePassword = true)
{
$sourceClass = self::$data_class;
$SNG_member = singleton($sourceClass);
$fieldList = $SNG_member->summaryFields();
$memberDbFields = DataObject::database_fields('Member');
$csvFieldList = array();
foreach ($memberDbFields as $field => $dbFieldType) {
$csvFieldList[$field] = $field;
}
if ($group) {
if (is_object($group)) {
$this->group = $group;
} elseif (is_numeric($group)) {
$this->group = DataObject::get_by_id('Group', $group);
}
} else {
if (isset($_REQUEST['ctf'][$this->Name()]["ID"]) && is_numeric($_REQUEST['ctf'][$this->Name()]["ID"])) {
$this->group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->Name()]["ID"]);
}
}
if (!$hidePassword) {
$fieldList["SetPassword"] = "Password";
}
$this->hidePassword = $hidePassword;
// @todo shouldn't this use $this->group? It's unclear exactly
// what group it should be customising the custom Member set with.
if ($members && $group) {
$this->setCustomSourceItems($this->memberListWithGroupID($members, $group));
}
parent::__construct($controller, $name, $sourceClass, $fieldList);
$SQL_search = isset($_REQUEST['MemberSearch']) ? Convert::raw2sql($_REQUEST['MemberSearch']) : null;
if (!empty($_REQUEST['MemberSearch'])) {
$searchFilters = array();
foreach ($SNG_member->searchableFields() as $fieldName => $fieldSpec) {
if (strpos($fieldName, '.') === false) {
$searchFilters[] = "\"{$fieldName}\" LIKE '%{$SQL_search}%'";
}
}
$this->sourceFilter[] = '(' . implode(' OR ', $searchFilters) . ')';
}
if ($this->group) {
$groupIDs = array($this->group->ID);
if ($this->group->AllChildren()) {
$groupIDs = array_merge($groupIDs, $this->group->AllChildren()->column('ID'));
}
$this->sourceFilter[] = sprintf('"Group_Members"."GroupID" IN (%s)', implode(',', $groupIDs));
}
$this->sourceJoin = " INNER JOIN \"Group_Members\" ON \"MemberID\"=\"Member\".\"ID\"";
$this->setFieldListCsv($csvFieldList);
$this->setPageSize($this->stat('page_size'));
}
示例5: onBeforeWrite
function onBeforeWrite()
{
parent::onBeforeWrite();
if (!$this->isInDb()) {
if ($this->Type) {
$this->ClassName = $this->Type;
}
foreach (DataObject::database_fields($this->ClassName) as $fieldName => $fieldType) {
$this->{$fieldName} = $this->record[$fieldName . "-for-" . $this->ClassName];
}
$this->Label = $this->record["Label-for-" . $this->ClassName];
}
}
示例6: getElasticaFields
/**
* Gets an array of elastic field definitions.
*
* @return array
*/
public function getElasticaFields()
{
$db = \DataObject::database_fields(get_class($this->owner));
$fields = $this->owner->searchableFields();
$result = array();
foreach ($fields as $name => $params) {
$type = null;
$spec = array();
if (array_key_exists($name, $db)) {
$class = $db[$name];
if ($pos = strpos($class, '(')) {
$class = substr($class, 0, $pos);
}
if (array_key_exists($class, self::$mappings)) {
$spec['type'] = self::$mappings[$class];
}
}
$result[$name] = $spec;
}
$result['LastEdited'] = array('type' => 'date');
$result['Created'] = array('type' => 'date');
$result['ID'] = array('type' => 'integer');
$result['ParentID'] = array('type' => 'integer');
$result['Sort'] = array('type' => 'integer');
$result['Name'] = array('type' => 'string');
$result['MenuTitle'] = array('type' => 'string');
$result['ShowInSearch'] = array('type' => 'integer');
$result['ClassName'] = array('type' => 'string');
$result['ClassNameHierarchy'] = array('type' => 'string');
// fix up dates
foreach ($result as $field => $spec) {
if (isset($spec['type']) && $spec['type'] == 'date') {
$spec['format'] = 'yyyy-MM-dd HH:mm:ss';
$result[$field] = $spec;
}
}
if (isset($result['Content']) && count($result['Content'])) {
$spec = $result['Content'];
$spec['store'] = false;
$result['Content'] = $spec;
}
if (method_exists($this->owner, 'updateElasticMappings')) {
$this->owner->updateElasticMappings($result);
}
$this->owner->extend('updateElasticMappings', $result);
return $result;
}
示例7: sendUpdateNotification
public function sendUpdateNotification($data)
{
$name = $data['FirstName'] . " " . $data['Surname'];
$body = "{$name} has updated their details via the website. Here is the new information:<br/>";
$notifyOnFields = Member::config()->frontend_update_notification_fields ?: DataObject::database_fields('Member');
$changedFields = $this->member->getChangedFields(true, 2);
$send = false;
foreach ($changedFields as $key => $field) {
if (in_array($key, $notifyOnFields)) {
$body .= "<br/><strong>{$key}:</strong><br/>" . "<strike style='color:red;'>" . $field['before'] . "</strike><br/>" . "<span style='color:green;'>" . $field['after'] . "</span><br/>";
$send = true;
}
}
if ($send) {
$email = new Email(Email::config()->admin_email, Email::config()->admin_email, "Member details update: {$name}", $body);
$email->send();
}
}
示例8: getElasticaFields
/**
* Gets an array of elastic field definitions.
*
* @return array
*/
public function getElasticaFields()
{
$db = \DataObject::database_fields(get_class($this->owner));
$fields = $this->owner->searchableFields();
$result = array();
foreach ($fields as $name => $params) {
$type = null;
$spec = array();
if (array_key_exists($name, $db)) {
$class = $db[$name];
if ($pos = strpos($class, '(')) {
$class = substr($class, 0, $pos);
}
if (array_key_exists($class, self::$mappings)) {
$spec['type'] = self::$mappings[$class];
}
}
$result[$name] = $spec;
}
return $result;
}
示例9: testClassNameSpecGeneration
/**
* Tests the generation of the ClassName spec and ensure it's not unnecessarily influenced
* by the order of classnames of existing records
*/
public function testClassNameSpecGeneration()
{
// Test with blank entries
DataObject::clear_classname_spec_cache();
$fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO');
$this->assertEquals("Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')", $fields['ClassName']);
// Test with instance of subclass
$item1 = new DataObjectSchemaGenerationTest_IndexDO();
$item1->write();
DataObject::clear_classname_spec_cache();
$fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO');
$this->assertEquals("Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')", $fields['ClassName']);
$item1->delete();
// Test with instance of main class
$item2 = new DataObjectSchemaGenerationTest_DO();
$item2->write();
DataObject::clear_classname_spec_cache();
$fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO');
$this->assertEquals("Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')", $fields['ClassName']);
$item2->delete();
// Test with instances of both classes
$item1 = new DataObjectSchemaGenerationTest_IndexDO();
$item1->write();
$item2 = new DataObjectSchemaGenerationTest_DO();
$item2->write();
DataObject::clear_classname_spec_cache();
$fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO');
$this->assertEquals("Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')", $fields['ClassName']);
$item1->delete();
$item2->delete();
}
示例10: database_is_ready
/**
* Checks the database is in a state to perform security checks.
* See {@link DatabaseAdmin->init()} for more information.
*
* @return bool
*/
public static function database_is_ready()
{
// Used for unit tests
if (self::$force_database_is_ready !== NULL) {
return self::$force_database_is_ready;
}
if (self::$database_is_ready) {
return self::$database_is_ready;
}
$requiredTables = ClassInfo::dataClassesFor('Member');
$requiredTables[] = 'Group';
$requiredTables[] = 'Permission';
foreach ($requiredTables as $table) {
// Skip test classes, as not all test classes are scaffolded at once
if (is_subclass_of($table, 'TestOnly')) {
continue;
}
// if any of the tables aren't created in the database
if (!ClassInfo::hasTable($table)) {
return false;
}
// HACK: DataExtensions aren't applied until a class is instantiated for
// the first time, so create an instance here.
singleton($table);
// if any of the tables don't have all fields mapped as table columns
$dbFields = DB::field_list($table);
if (!$dbFields) {
return false;
}
$objFields = DataObject::database_fields($table, false);
$missingFields = array_diff_key($objFields, $dbFields);
if ($missingFields) {
return false;
}
}
self::$database_is_ready = true;
return true;
}
示例11: XML_val
/**
* Entry point for being called from a template.
*
* This gets the aggregate function
*
*/
public function XML_val($name, $args = null, $cache = false)
{
$func = strtoupper(strpos($name, 'get') === 0 ? substr($name, 3) : $name);
$attribute = $args ? $args[0] : 'ID';
$table = null;
foreach (ClassInfo::ancestry($this->type, true) as $class) {
$fields = DataObject::database_fields($class);
if (array_key_exists($attribute, $fields)) {
$table = $class;
break;
}
}
if (!$table) {
user_error("Couldn't find table for field {$attribute} in type {$this->type}", E_USER_ERROR);
}
$query = $this->query("{$func}(\"{$table}\".\"{$attribute}\")");
// Cache results of this specific SQL query until flushCache() is triggered.
$cachekey = sha1($query->sql());
$cache = self::cache();
if (!($result = $cache->load($cachekey))) {
$result = (string) $query->execute()->value();
if (!$result) {
$result = '0';
}
$cache->save($result, null, array('aggregate', preg_replace('/[^a-zA-Z0-9_]/', '_', $this->type)));
}
return $result;
}
示例12: cleanup
/**
* Remove invalid records from tables - that is, records that don't have
* corresponding records in their parent class tables.
*/
public function cleanup()
{
$allClasses = get_declared_classes();
foreach ($allClasses as $class) {
if (get_parent_class($class) == 'DataObject') {
$baseClasses[] = $class;
}
}
foreach ($baseClasses as $baseClass) {
// Get data classes
$subclasses = ClassInfo::subclassesFor($baseClass);
unset($subclasses[0]);
foreach ($subclasses as $k => $subclass) {
if (DataObject::database_fields($subclass)) {
unset($subclasses[$k]);
}
}
if ($subclasses) {
$records = DB::query("SELECT * FROM \"{$baseClass}\"");
foreach ($subclasses as $subclass) {
$recordExists[$subclass] = DB::query("SELECT \"ID\" FROM \"{$subclass}\"")->keyedColumn();
}
foreach ($records as $record) {
foreach ($subclasses as $subclass) {
$id = $record['ID'];
if ($record['ClassName'] != $subclass && !is_subclass_of($record['ClassName'], $subclass) && isset($recordExists[$subclass][$id])) {
$sql = "DELETE FROM \"{$subclass}\" WHERE \"ID\" = {$record['ID']}";
echo "<li>{$sql}";
DB::query($sql);
}
}
}
}
}
}
示例13: recursiveRelationships
/**
* Recursively return the relationships for a given data object map.
*/
private function recursiveRelationships(&$object, $attributeVisibility = false, $cache = array())
{
$output = array();
// Cache relationship data objects to prevent infinite recursion.
if (!in_array("{$object['ClassName']} {$object['ID']}", $cache)) {
$cache[] = "{$object['ClassName']} {$object['ID']}";
foreach ($object as $attribute => $value) {
if ($attribute !== 'ClassName' && $attribute !== 'RecordClassName') {
// Grab the name of a relationship.
$relationship = substr($attribute, strlen($attribute) - 2) === 'ID' && strlen($attribute) > 2 ? substr($attribute, 0, -2) : null;
if ($relationship && ($relationObject = DataObject::get_by_id($object['ClassName'], $object['ID'])) && $relationObject->hasMethod($relationship) && $value != 0) {
// Grab the relationship.
$relationObject = $relationObject->{$relationship}();
// Make sure recursive relationships are enabled.
if (!$this->recursiveRelationships) {
$output[$relationship] = array($relationObject->ClassName => array('ID' => (string) $relationObject->ID));
continue;
}
$temporaryMap = $relationObject->toMap();
if ($attributeVisibility) {
// Grab the attribute visibility.
$class = is_subclass_of($relationObject->ClassName, 'SiteTree') ? 'SiteTree' : (is_subclass_of($relationObject->ClassName, 'File') ? 'File' : $relationObject->ClassName);
$relationConfiguration = DataObjectOutputConfiguration::get_one('DataObjectOutputConfiguration', "IsFor = '" . Convert::raw2sql($class) . "'");
$relationVisibility = $relationConfiguration && $relationConfiguration->APIwesomeVisibility ? explode(',', $relationConfiguration->APIwesomeVisibility) : null;
$columns = array();
foreach (ClassInfo::subclassesFor($class) as $subclass) {
// Prepend the table names.
$subclassColumns = array();
foreach (DataObject::database_fields($subclass) as $column => $type) {
$subclassColumns["{$subclass}.{$column}"] = $type;
}
$columns = array_merge($columns, $subclassColumns);
}
array_shift($columns);
// Make sure this relationship has visibility customisation.
if (is_null($relationVisibility) || count($relationVisibility) !== count($columns) || !in_array('1', $relationVisibility)) {
$output[$relationship] = array($relationObject->ClassName => array('ID' => (string) $relationObject->ID));
continue;
}
// Grab all data object visible attributes.
$select = array('ClassName' => $relationObject->ClassName, 'ID' => $relationObject->ID);
$iteration = 0;
foreach ($columns as $relationshipAttribute => $relationshipType) {
if (isset($relationVisibility[$iteration]) && $relationVisibility[$iteration]) {
$split = explode('.', $relationshipAttribute);
$relationshipAttribute = count($split) === 2 ? $split[1] : $relationshipAttribute;
if (isset($temporaryMap[$relationshipAttribute]) && $temporaryMap[$relationshipAttribute]) {
// Retrieve the relationship value, and compose any asset file paths.
$relationshipValue = $temporaryMap[$relationshipAttribute];
$select[$relationshipAttribute] = (strpos(strtolower($relationshipAttribute), 'file') !== false || strpos(strtolower($relationshipAttribute), 'image') !== false) && strpos($relationshipValue, 'assets/') !== false ? Director::absoluteURL($relationshipValue) : (is_integer($relationshipValue) ? (string) $relationshipValue : $relationshipValue);
}
}
$iteration++;
}
} else {
$select = $temporaryMap;
}
// Check the corresponding relationship.
$output[$relationship] = array($relationObject->ClassName => $this->recursiveRelationships($select, $attributeVisibility, $cache));
} else {
// Compose any asset file paths.
$output[$attribute] = (strpos(strtolower($attribute), 'file') !== false || strpos(strtolower($attribute), 'image') !== false) && strpos($value, 'assets/') !== false ? Director::absoluteURL($value) : (is_integer($value) ? (string) $value : $value);
}
}
}
} else {
// This relationship has previously been cached.
$output['ID'] = $object['ID'];
}
// Return the visible relationship attributes.
return $output;
}
示例14: augmentDatabase
function augmentDatabase()
{
$classTable = $this->owner->class;
$isRootClass = $this->owner->class == ClassInfo::baseDataClass($this->owner->class);
// Build a list of suffixes whose tables need versioning
$allSuffixes = array();
foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) {
if ($this->owner->hasExtension($versionableExtension)) {
$allSuffixes = array_merge($allSuffixes, (array) $suffixes);
foreach ((array) $suffixes as $suffix) {
$allSuffixes[$suffix] = $versionableExtension;
}
}
}
// Add the default table with an empty suffix to the list (table name = class name)
array_push($allSuffixes, '');
foreach ($allSuffixes as $key => $suffix) {
// check that this is a valid suffix
if (!is_int($key)) {
continue;
}
if ($suffix) {
$table = "{$classTable}_{$suffix}";
} else {
$table = $classTable;
}
if ($fields = DataObject::database_fields($this->owner->class)) {
$indexes = $this->owner->databaseIndexes();
if ($suffix && ($ext = $this->owner->getExtensionInstance($allSuffixes[$suffix]))) {
if (!$ext->isVersionedTable($table)) {
continue;
}
$ext->setOwner($this->owner);
$fields = $ext->fieldsInExtraTables($suffix);
$ext->clearOwner();
$indexes = $fields['indexes'];
$fields = $fields['db'];
}
// Create tables for other stages
foreach ($this->stages as $stage) {
// Extra tables for _Live, etc.
if ($stage != $this->defaultStage) {
DB::requireTable("{$table}_{$stage}", $fields, $indexes, false);
}
// Version fields on each root table (including Stage)
/*
if($isRootClass) {
$stageTable = ($stage == $this->defaultStage) ? $table : "{$table}_$stage";
$parts=Array('datatype'=>'int', 'precision'=>11, 'null'=>'not null', 'default'=>(int)0);
$values=Array('type'=>'int', 'parts'=>$parts);
DB::requireField($stageTable, 'Version', $values);
}
*/
}
if ($isRootClass) {
// Create table for all versions
$versionFields = array_merge(self::$db_for_versions_table, (array) $fields);
$versionIndexes = array_merge(self::$indexes_for_versions_table, (array) $indexes);
} else {
// Create fields for any tables of subclasses
$versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int"), (array) $fields);
$versionIndexes = array_merge(array('RecordID_Version' => array('type' => 'unique', 'value' => 'RecordID,Version'), 'RecordID' => true, 'Version' => true), (array) $indexes);
}
if (DB::getConn()->hasTable("{$table}_versions")) {
// Fix data that lacks the uniqueness constraint (since this was added later and
// bugs meant that the constraint was validated)
$duplications = DB::query("SELECT MIN(\"ID\") AS \"ID\", \"RecordID\", \"Version\" \n\t\t\t\t\t\tFROM \"{$table}_versions\" GROUP BY \"RecordID\", \"Version\" \n\t\t\t\t\t\tHAVING COUNT(*) > 1");
foreach ($duplications as $dup) {
DB::alteration_message("Removing {$table}_versions duplicate data for " . "{$dup['RecordID']}/{$dup['Version']}", "deleted");
DB::query("DELETE FROM \"{$table}_versions\" WHERE \"RecordID\" = {$dup['RecordID']}\n\t\t\t\t\t\t\tAND \"Version\" = {$dup['Version']} AND \"ID\" != {$dup['ID']}");
}
// Remove junk which has no data in parent classes. Only needs to run the following
// when versioned data is spread over multiple tables
if (!$isRootClass && ($versionedTables = ClassInfo::dataClassesFor($table))) {
foreach ($versionedTables as $child) {
if ($table == $child) {
break;
}
// only need subclasses
$count = DB::query("\n\t\t\t\t\t\t\t\tSELECT COUNT(*) FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t")->value();
if ($count > 0) {
DB::alteration_message("Removing orphaned versioned records", "deleted");
$effectedIDs = DB::query("\n\t\t\t\t\t\t\t\t\tSELECT \"{$table}_versions\".\"ID\" FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t\t")->column();
if (is_array($effectedIDs)) {
foreach ($effectedIDs as $key => $value) {
DB::query("DELETE FROM \"{$table}_versions\" WHERE \"{$table}_versions\".\"ID\" = '{$value}'");
}
}
}
}
}
}
DB::requireTable("{$table}_versions", $versionFields, $versionIndexes);
} else {
DB::dontRequireTable("{$table}_versions");
foreach ($this->stages as $stage) {
if ($stage != $this->defaultStage) {
DB::dontrequireTable("{$table}_{$stage}");
}
}
//.........这里部分代码省略.........
示例15: writeClassTable
/**
* @param $objects
* @param $class
* @param $table
* @param bool $setID
* @param bool $update
* @throws Exception
*/
private function writeClassTable($objects, $class, $table, $setID = false, $update = false)
{
$fields = DataObject::database_fields($class);
$singleton = singleton($class);
$fields = array_filter(array_keys($fields), function ($field) use($singleton) {
return $singleton->hasOwnTableDatabaseField($field);
});
if ($setID || $update) {
array_unshift($fields, 'ID');
}
$typeLookup = array('ID' => 'i');
foreach ($fields as $field) {
$dbObject = $singleton->dbObject($field);
if ($dbObject instanceof Boolean || $dbObject instanceof Int) {
$typeLookup[$field] = 'i';
} else {
if ($dbObject instanceof Float || $dbObject instanceof Decimal || $dbObject instanceof Money) {
$typeLookup[$field] = 'd';
} else {
$typeLookup[$field] = 's';
}
}
}
$inserts = array();
$insert = '(' . implode(',', array_fill(0, count($fields), '?')) . ')';
$types = '';
$params = array();
foreach ($objects as $obj) {
$record = $this->dataObjectRecordProperty->getValue($obj);
foreach ($fields as $field) {
$type = $typeLookup[$field];
$types .= $type;
$value = isset($record[$field]) ? $record[$field] : $obj->getField($field);
if (is_bool($value)) {
$value = (int) $value;
}
if ($type != 's' && !$value) {
$value = 0;
}
$params[] = $value;
}
$inserts[] = $insert;
}
array_unshift($params, $types);
$columns = implode(', ', array_map(function ($name) {
return "`{$name}`";
}, $fields));
$inserts = implode(',', $inserts);
$sql = "INSERT INTO `{$table}` ({$columns}) VALUES {$inserts}";
if ($update) {
$mappings = array();
foreach ($fields as $field) {
if ($field !== 'ID') {
$mappings[] = "`{$field}` = VALUES(`{$field}`)";
}
}
$mappings = implode(',', $mappings);
$sql .= " ON DUPLICATE KEY UPDATE {$mappings}";
}
$this->executeQuery($sql, $params);
}