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

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
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