ilias - 在 ilUIHookPluginGUI 中获取高级元数据的更简单方法?

标签 ilias

我目前正在为 ILIAS 编写一个插件。插件本身一点也不复杂,但它包含几个问题,而我认为我们可以让它变得更简单。

情况如下:我们在用户定义的元数据部分添加了一个全局高级元数据字段,带有双射标识符。该字段在名为类(class)的存储库中被激活。我们已经使用基于ilUIHookPluginGUI的插件操作了GUI。

这个的代码是......好吧......你自己看看。

首先,我们在插件的 ConfigGUI 的设置中保存新元数据字段的 ID:

$field_settings = new ilSetting("foo");
$field_id_value = $field_settings->set("field_id",$_POST["field_id"]);

在我们扩展 ilUIHookPluginGUI 的类中,我们正在加载如下设置,并且我们有字段的 ID:

$field_settings = new ilSetting("foo");
$field_id_value = $field_settings->get("field_id");

现在是有趣的部分。有了这个ID和对象的ref_id(好吧,我们也加载对象来获取ObjId)我们可以加载类(class)设置的元数据字段的值:

$object = \ilObjectFactory::getInstanceByRefId($_GET[ 'ref_id' ]);
$obj_id = $object->getId();

$result = $DIC->database()->query("SELECT value FROM adv_md_values_text WHERE obj_id = '".$obj_id."' AND field_id = '".$field_id_value."'");
$value = $DIC->database()->fetchAssoc($result);
$is_active = $value['value'];

问题是......是否有更简单的方法来实现我的结果?

最好的, 劳拉

最佳答案

好问题。首先,请注意,我认为 ILIAS 中的高级元数据服务缺乏一个很好的自述文件来明确说明接口(interface)为您的任务提供的 Hook 。前段时间,我也不得不处理这个服务,遇到了类似的问题。希望您的问题有助于更好地记录这一点,我自己也很期待其他建议,因为我知道我的也不是很好。如果您有任何资源,我们将不胜感激帮助插入引入良好的服务自述文件,并插入服务朝着使用具有清晰界面的存储库模式发展。

关于您提出的可以改进的问题:我在代码行中看到了三个主要问题:

  1. 在您的插件配置中存储一个 ID。对于非技术人员,您的插件将无法配置。然而,这对您来说也很容易出错,请考虑将测试安装的内容导出导入到生产环境中。
  2. 通过查询而不是服务访问值。
  3. 在代码中使用新的静态函数使其无法测试。

第一步 让我们从第一个开始。请注意,如果不引入一个新问题(一个新查询),我就无法解决这个问题。不好我知道。我希望有更好的解决方案,经过快速研究后我没有找到。您存储 id,因为字段标题不是安全唯一的,对吗?这是正确的,但是,您可以考虑存储 field_title、record_title 和(可能)范围的三元组。请注意,您可能不需要范围,因为您希望在全局范围内使用它。一个函数返回你和包含 field_id 和 record_id 的数组可能看起来像这样:

function getFieldAndRecordIdByFieldTitles($field_title, $record_title, $scope_title){
        $query = "select field.field_id,field.record_id from adv_mdf_definition as field
            INNER JOIN adv_md_record as record ON record.record_id = field.record_id
            INNER JOIN adv_md_record_scope as scope ON scope.record_id = field.record_id
            INNER JOIN object_reference as ref ON scope.ref_id = ref.ref_id
            INNER JOIN object_data as scope_data ON ref.obj_id = scope_data.obj_id
            WHERE field.title='$field_title' AND record.title='$record_title' AND scope_data.title = '$scope_title'";

        $set = $this->dic()->database()->query($query);
        if($row = $this->dic()->database()->fetchAssoc($set))
        {
            return array_values($row);
        }
    }

然后像这样获取你的值:

list($field_id,$record_id) = getFieldAndRecordIdByFieldTitles("my_field", "my_record", "my_scope");

请注意,我知道我在这里引入了一个新查询。对不起,这是我能想到的最好的。我相信您会找到更好的解决方案,如果您进行了一些研究,请告诉我们是否成功。但是,我们将在下一步中删除一个。

第 2 步 使用未记录的服务,从高级元数据中获取您的值(value)。由于您现在有了记录 ID 和字段 ID,您可以这样做:

$record_values = new ilAdvancedMDValues($record_id, $obj_id);
$record_values->read();
$ADTGroup = $ilAdvancedMDValues->getADTGroup();
$ADT = $ilADTGroup->getElement($field_id);
$value = $ADT->getText(); 
/**if you have text, others are possible, such as:              
        switch (true) {
            case ($ADT instanceof ilADTText):
                break;
            case ($ADT instanceof ilADTDate):
                $value = $ADT->getDate();
                break;
            case ($ADT instanceof ilADTExternalLink):
                $... = $ADT->getUrl();
                $... = $ADT->getTitle();
                break;
            case ($ADT instanceof ilADTInternalLink):
                $... = $ADT->setTargetRefId($value);
        }
**/

请注意,ADT 也没有记录在案。可能有更好的方法来从中获取值(value)。

第 3 步 将您的 statics 和 new 包装成一些可注入(inject)的依赖项。我通常使用臃肿的构造函数模式来做到这一点。看起来像这样:

public function __construct(InjectedSettings $mySettings = null)
{
    if (!$mySettings) //Case in the default scenario
    {
        $this->mySettings = new InjectedSettings();
    } else //used e.g. for unit tests, where you can stuff the constructor with a mock
    {
        $this->mySettings = $mySettings;
    }
    $this->mySettings->doSometing();
}

请注意,这不是真正的部门。注入(inject),你仍然使用新的,但我认为使用 dep 是一个非常可行的修复。至少为 ilias 中的测试上下文注入(inject)。

这有帮助吗?我希望会有其他(也有更好的答案)。

关于ilias - 在 ilUIHookPluginGUI 中获取高级元数据的更简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54201342/

相关文章:

php - 在 ILIAS 中使用 Flysystem 附加到文件

ilias - 开发 ILIAS 插件

php - 在 null 上调用成员函数 tableColumnExists()