Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(Core): Add entities_id and is_recursive fields to correctly filter data from the API #858

Merged
merged 21 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion inc/abstractcontainerinstance.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,56 @@
* -------------------------------------------------------------------------
*/

abstract class PluginFieldsAbstractContainerInstance extends CommonDBTM
abstract class PluginFieldsAbstractContainerInstance extends CommonDBChild
{
public static $itemtype = 'itemtype';
public static $items_id = 'items_id';

public static $mustBeAttached = false;

/**
* This function relies on the static property `static::$plugins_forward_entity`,
* which should be populated using the following method (from setup):
*
* Plugin::registerClass(
* PluginFields<Itemtype><name>,
* ['forwardentityfrom' => <Itemtype>]
* );
*
* However, the order in which plugins are loaded can affect the behavior.
* For example, if a container is defined on a `GenericObject` itemtype and
* the `fields` plugin initializes before the `genericobject` plugin, the
* `itemtype` for the container will not yet exist, leading to potential issues.
*
* Modification of this function to meet specific requirements.
*/
public function addNeededInfoToInput($input)
trasher marked this conversation as resolved.
Show resolved Hide resolved
{
if ($this->tryEntityForwarding()) {
$completeinput = array_merge($this->fields, $input);
if (
$itemToGetEntity = static::getItemFromArray(
static::$itemtype,
static::$items_id,
$completeinput,
)
) {
if (
($itemToGetEntity instanceof CommonDBTM)
) {
if ($itemToGetEntity->isEntityAssign()) {
$input['entities_id'] = $itemToGetEntity->getEntityID();
}

if ($itemToGetEntity->maybeRecursive()) {
$input['is_recursive'] = intval($itemToGetEntity->isRecursive());
}
}
}
}
return $input;
}

public static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = [])
{
if (!is_array($values)) {
Expand Down
105 changes: 103 additions & 2 deletions templates/container.class.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance

$obj = new self();
$table = $obj->getTable();
$migration = new PluginFieldsMigration(0);

// create Table
if (!$DB->tableExists($table)) {
Expand All @@ -32,10 +33,8 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance
$result = $DB->query("SHOW COLUMNS FROM `$table`");
if ($result && $DB->numrows($result) > 0) {
$changed = false;
$migration = new PluginFieldsMigration(0);
while ($data = $DB->fetchAssoc($result)) {
if (str_starts_with($data['Field'], 'itemtype_') && $data['Null'] !== 'YES') {
Toolbox::logDebug($data);
$migration->changeField($table, $data['Field'], $data['Field'], "varchar(100) DEFAULT NULL");
$changed = true;
}
Expand All @@ -45,6 +44,108 @@ class %%CLASSNAME%% extends PluginFieldsAbstractContainerInstance
}
}
}

/**
* Adds the 'entities_id' field to the database table and migrates existing data.
*
* This block ensures that the 'entities_id' field is created and populated if it
* associated item type requires entity assignment
*/
if (getItemForItemtype("%%ITEMTYPE%%")->isEntityAssign() && !$DB->fieldExists($table, 'entities_id')) {
$migration->addField($table, 'entities_id', 'fkey', ['after' => 'plugin_fields_containers_id']);
$migration->addKey($table, 'entities_id');
$migration->executeMigration();

// migrate data
$query = $DB->buildUpdate(
$table,
['entities_id' => new QueryParam()],
['id' => new QueryParam()]
);
$stmt = $DB->prepare($query);

//load all entries
$data = $DB->request(
[
'SELECT' => '*',
'FROM' => $table,
]
);

foreach ($data as $fields) {
//load related item
$related_item = $DB->request(
[
'SELECT' => '*',
'FROM' => getTableForItemType($fields['itemtype']),
'WHERE' => [
'id' => $fields['items_id'],
]
]
)->current();

stonebuzz marked this conversation as resolved.
Show resolved Hide resolved
//update if needed
if ($fields['entities_id'] != $related_item['entities_id']) {
$stmt->bind_param(
'ii',
$related_item['entities_id'],
$fields['id']
);
$stmt->execute();
}
}
}

/**
* Adds the 'is_recursive' field to the database table and migrates existing data.
*
* This block ensures that the 'is_recursive' field is created and populated if it
* associated item type requires recursive assignment
*/
if (getItemForItemtype("%%ITEMTYPE%%")->maybeRecursive() && !$DB->fieldExists($table, 'is_recursive')) {
$migration->addField($table, 'is_recursive', 'bool', ['after' => 'entities_id']);
$migration->addKey($table, 'is_recursive');
$migration->executeMigration();

//migrate data
$query = $DB->buildUpdate(
$table,
['is_recursive' => new QueryParam()],
['id' => new QueryParam()]
);
$stmt = $DB->prepare($query);

//load all entries
$data = $DB->request(
[
'SELECT' => '*',
'FROM' => $table,
]
);

foreach ($data as $fields) {
//load related item
$related_item = $DB->request(
[
'SELECT' => '*',
'FROM' => getTableForItemType($fields['itemtype']),
'WHERE' => [
'id' => $fields['items_id'],
]
]
)->current();

stonebuzz marked this conversation as resolved.
Show resolved Hide resolved
//update if needed
if ($fields['is_recursive'] != $related_item['is_recursive']) {
$stmt->bind_param(
'ii',
$related_item['is_recursive'],
$fields['id']
);
$stmt->execute();
}
}
}
}

static function uninstall() {
Expand Down