1<?php
2
3/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5include_once("./Services/Skill/interfaces/interface.ilSkillUsageInfo.php");
6
7/**
8 * Skill usage
9 *
10 * With this class a general skill use by an object (identified by its obj_id)
11 * is registered or unregistered.
12 *
13 * The class maintains skill usages of the following types
14 * - GENERAL: General use submitted by an object, saved in table "skl_usage"
15 * - USER_ASSIGNED: Skill level is assigned to a user (tables skl_user_skill_level and skl_user_has_level)
16 * - PERSONAL_SKILL: table skl_personal_skill (do we need that?)
17 * - USER_MATERIAL: User has assigned material to the skill
18 * - SELF_EVAL: User has self evaluated (may be USER_ASSIGNED in the future)
19 * - PROFILE: Skill is used in skill profile (table "skl_profile_level")
20 * - RESOURCE: A resource is assigned to a skill level (table "skl_skill_resource")
21 *
22 * @author Alex Killing <alex.killing@gmx.de>
23 * @version $Id$
24 * @ingroup ServicesSkill
25 */
26class ilSkillUsage implements ilSkillUsageInfo
27{
28    const TYPE_GENERAL = "gen";
29    const USER_ASSIGNED = "user";
30    const PERSONAL_SKILL = "pers";
31    const USER_MATERIAL = "mat";
32    const SELF_EVAL = "seval";
33    const PROFILE = "prof";
34    const RESOURCE = "res";
35
36    // these classes implement the ilSkillUsageInfo interface
37    // currently this array is ok, we do not need any subscription model here
38    /*protected $classes = array("ilBasicSkill", "ilPersonalSkill",
39        "ilSkillSelfEvaluation", "ilSkillProfile", "ilSkillResources", "ilSkillUsage");*/
40    protected $classes = array("ilBasicSkill", "ilPersonalSkill", "ilSkillProfile",  "ilSkillResources", "ilSkillUsage");
41
42    /**
43     * Set usage
44     *
45     * @param int $a_obj_id object id
46     * @param int $a_skill_id skill id
47     * @param int $a_tref_id tref id
48     * @param bool $a_use in use true/false
49     */
50    public static function setUsage($a_obj_id, $a_skill_id, $a_tref_id, $a_use = true)
51    {
52        global $DIC;
53
54        $ilDB = $DIC->database();
55
56        if ($a_use) {
57            $ilDB->replace(
58                "skl_usage",
59                array(
60                    "obj_id" => array("integer", $a_obj_id),
61                    "skill_id" => array("integer", $a_skill_id),
62                    "tref_id" => array("integer", $a_tref_id)
63                    ),
64                array()
65                );
66        } else {
67            $ilDB->manipulate(
68                $q = "DELETE FROM skl_usage WHERE " .
69                " obj_id = " . $ilDB->quote($a_obj_id, "integer") .
70                " AND skill_id = " . $ilDB->quote($a_skill_id, "integer") .
71                " AND tref_id = " . $ilDB->quote($a_tref_id, "integer")
72                );
73            //echo $q; exit;
74        }
75    }
76
77    /**
78     * Get usages
79     *
80     * @param int $a_skill_id skill id
81     * @param int $a_tref_id tref id
82     * @return array of int object ids
83     */
84    public static function getUsages($a_skill_id, $a_tref_id)
85    {
86        global $DIC;
87
88        $ilDB = $DIC->database();
89
90        $set = $ilDB->query(
91            "SELECT obj_id FROM skl_usage " .
92            " WHERE skill_id = " . $ilDB->quote($a_skill_id, "integer") .
93            " AND tref_id = " . $ilDB->quote($a_tref_id, "integer")
94            );
95        $obj_ids = array();
96        while ($rec = $ilDB->fetchAssoc($set)) {
97            $obj_ids[] = $rec["obj_id"];
98        }
99
100        return $obj_ids;
101    }
102
103    /**
104     * Get usage info
105     *
106     * @param array $a_cskill_ids skill ids
107     * @param array $a_usages usages array
108     */
109    public static function getUsageInfo($a_cskill_ids, &$a_usages)
110    {
111        global $DIC;
112
113        $ilDB = $DIC->database();
114
115        self::getUsageInfoGeneric(
116            $a_cskill_ids,
117            $a_usages,
118            ilSkillUsage::TYPE_GENERAL,
119            "skl_usage",
120            "obj_id"
121        );
122    }
123
124    /**
125     * Get standard usage query
126     *
127     * @param array $a_cskill_ids skill ids
128     * @param array $a_usages usages array
129     */
130    public static function getUsageInfoGeneric(
131        $a_cskill_ids,
132        &$a_usages,
133        $a_usage_type,
134        $a_table,
135        $a_key_field,
136        $a_skill_field = "skill_id",
137        $a_tref_field = "tref_id"
138    ) {
139        global $DIC;
140
141        $ilDB = $DIC->database();
142
143        if (count($a_cskill_ids) == 0) {
144            return;
145        }
146
147        $w = "WHERE";
148        $q = "SELECT " . $a_key_field . ", " . $a_skill_field . ", " . $a_tref_field . " FROM " . $a_table . " ";
149        foreach ($a_cskill_ids as $sk) {
150            $q .= $w . " (" . $a_skill_field . " = " . $ilDB->quote($sk["skill_id"], "integer") .
151            " AND " . $a_tref_field . " = " . $ilDB->quote($sk["tref_id"], "integer") . ") ";
152            $w = "OR";
153        }
154        $q .= " GROUP BY " . $a_key_field . ", " . $a_skill_field . ", " . $a_tref_field;
155
156        $set = $ilDB->query($q);
157        while ($rec = $ilDB->fetchAssoc($set)) {
158            $a_usages[$rec[$a_skill_field] . ":" . $rec[$a_tref_field]][$a_usage_type][] =
159                    array("key" => $rec[$a_key_field]);
160        }
161    }
162
163
164    /**
165     * Get all usages info
166     *
167     * @param array of common skill ids ("skill_id" => skill_id, "tref_id" => tref_id)
168     * @return array usages
169     */
170    public function getAllUsagesInfo($a_cskill_ids)
171    {
172        $classes = $this->classes;
173
174        $usages = array();
175        foreach ($classes as $class) {
176            // make static call
177            include_once("./Services/Skill/classes/class." . $class . ".php");
178            //call_user_func($class.'::getUsageInfo', $a_cskill_ids, $usages);
179            $class::getUsageInfo($a_cskill_ids, $usages);
180        }
181        return $usages;
182    }
183
184    /**
185     * Get all usages info of subtree
186     *
187     * @param int $a_skill_id skill node id
188     * @param int $a_tref_id tref id
189     * @return array usages
190     */
191    public function getAllUsagesInfoOfSubtree($a_skill_id, $a_tref_id = 0)
192    {
193        // get nodes
194        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
195        $vtree = new ilVirtualSkillTree();
196        $nodes = $vtree->getSubTreeForCSkillId($a_skill_id . ":" . $a_tref_id);
197
198        return $this->getAllUsagesInfo($nodes);
199    }
200
201    /**
202     * Get all usages info of subtree
203     *
204     * @param array $a_cskill_ids array of common skill ids ("skill_id" => skill_id, "tref_id" => tref_id)
205     * @return array usages
206     */
207    public function getAllUsagesInfoOfSubtrees($a_cskill_ids)
208    {
209        // get nodes
210        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
211        $vtree = new ilVirtualSkillTree();
212        $allnodes = array();
213        foreach ($a_cskill_ids as $s) {
214            $nodes = $vtree->getSubTreeForCSkillId($s["skill_id"] . ":" . $s["tref_id"]);
215            foreach ($nodes as $n) {
216                $allnodes[] = $n;
217            }
218        }
219
220        return $this->getAllUsagesInfo($allnodes);
221    }
222
223    /**
224     * Get all usages of template
225     *
226     * @param int $a_tempate_id template
227     * @return array usages array
228     */
229    public function getAllUsagesOfTemplate($a_tempate_id)
230    {
231        $skill_logger = ilLoggerFactory::getLogger('skll');
232        $skill_logger->debug("ilSkillUsage: getAllUsagesOfTemplate(" . $a_tempate_id . ")");
233
234        // get all trefs for template id
235        include_once("./Services/Skill/classes/class.ilSkillTemplateReference.php");
236        $trefs = ilSkillTemplateReference::_lookupTrefIdsForTemplateId($a_tempate_id);
237
238        // get all usages of subtrees of template_id:tref
239        $cskill_ids = array();
240        foreach ($trefs as $tref) {
241            $cskill_ids[] = array("skill_id" => $a_tempate_id, "tref_id" => $tref);
242            $skill_logger->debug("ilSkillUsage: ... skill_id: " . $a_tempate_id . ", tref_id: " . $tref . ".");
243        }
244
245        $skill_logger->debug("ilSkillUsage: ... count cskill_ids: " . count($cskill_ids) . ".");
246
247        return $this->getAllUsagesInfoOfSubtrees($cskill_ids);
248    }
249
250    /**
251     * Get type info string
252     *
253     * @param string $a_type usage type
254     * @return string lang string
255     */
256    public static function getTypeInfoString($a_type)
257    {
258        global $DIC;
259
260        $lng = $DIC->language();
261
262        return $lng->txt("skmg_usage_type_info_" . $a_type);
263    }
264
265    /**
266     * Get type info string
267     *
268     * @param
269     * @return
270     */
271    public static function getObjTypeString($a_type)
272    {
273        global $DIC;
274
275        $lng = $DIC->language();
276
277        switch ($a_type) {
278            case self::TYPE_GENERAL:
279            case self::RESOURCE:
280                return $lng->txt("skmg_usage_obj_objects");
281                break;
282
283            case self::USER_ASSIGNED:
284            case self::PERSONAL_SKILL:
285            case self::USER_MATERIAL:
286            case self::SELF_EVAL:
287                return $lng->txt("skmg_usage_obj_users");
288                break;
289
290            case self::PROFILE:
291                return $lng->txt("skmg_usage_obj_profiles");
292                break;
293        }
294
295        return $lng->txt("skmg_usage_type_info_" . $a_type);
296    }
297}
298