Пример #1
0
    /**
     * Process the tags step
     *
     * @return  void
     */
    public function step_tags_process()
    {
        $id = Request::getInt('id', 0);
        $this->database->setQuery('SELECT 1 FROM #__author_assoc WHERE authorid = ' . User::get('id') . ' AND subtable = \'resources\' AND subid = ' . $id . '
			UNION
			SELECT 1 FROM #__resources WHERE id = ' . $id . ' AND (created_by = ' . User::get('id') . ' OR modified_by = ' . User::get('id') . ')
			UNION
			SELECT 1 FROM #__users u
			INNER JOIN #__user_usergroup_map cagam ON cagam.user_id = u.id
			INNER JOIN #__usergroups caag ON caag.id = cagam.group_id AND (caag.title = \'Super Administrator\' OR caag.title = \'Super Users\' OR caag.title = \'Administrator\')
			WHERE u.id = ' . User::get('id'));
        if (!$this->database->loadResult()) {
            App::abort(403, Lang::txt('Forbidden'));
            return;
        }
        $tags = preg_split('/,\\s*/', $_POST['tags']);
        $push = array();
        $map = array();
        $this->database->setQuery('SELECT fa.tag_id, t.raw_tag, fa.mandatory_depth AS minimum_depth, 0 AS actual_depth
			FROM #__focus_areas fa
			INNER JOIN #__tags t ON t.id = fa.tag_id
			INNER JOIN #__focus_area_resource_type_rel rtr ON rtr.focus_area_id = fa.id
			INNER JOIN #__resource_types rt ON rt.id = rtr.resource_type_id
			INNER JOIN #__resources r ON r.type = rt.id AND r.id = ' . $id . '
			WHERE fa.mandatory_depth IS NOT NULL AND fa.mandatory_depth > 0');
        $fas = $this->database->loadAssocList('raw_tag');
        foreach ($_POST as $k => $vs) {
            if (!preg_match('/^tagfa/', $k)) {
                continue;
            }
            if (!is_array($vs)) {
                $vs = array($vs);
            }
            foreach ($vs as $v) {
                $norm_tag = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($v));
                if (isset($map[$norm_tag])) {
                    continue;
                }
                $this->database->setQuery('SELECT t2.raw_tag AS fa, t2.id AS label_id, t.id
					FROM #__tags t
					INNER JOIN #__tags_object to1 ON to1.tbl = \'tags\' AND to1.label = \'label\' AND to1.objectid = t.id
					INNER JOIN #__tags t2 ON t2.id = to1.tagid
					INNER JOIN #__focus_areas fa ON fa.tag_id = to1.tagid
					WHERE t.tag = ' . $this->database->quote($norm_tag));
                if ($row = $this->database->loadAssoc()) {
                    $push[] = array($v, $norm_tag, $row['fa'], $row['id'], $row['label_id']);
                    $map[$norm_tag] = true;
                }
            }
        }
        $filtered = array();
        // only accept focus areas with parents if their parent is also checked
        foreach ($push as $idx => $tag) {
            $this->database->setQuery('SELECT t.tag, t.id
				FROM #__tags_object to1
				INNER JOIN #__tags t ON t.id = to1.tagid
				INNER JOIN #__tags_object to2 ON to2.tagid = ' . $tag[4] . ' AND to2.tbl = \'tags\' AND to2.objectid = to1.tagid
				WHERE to1.objectid = ' . $tag[3] . ' AND to1.tbl = \'tags\' AND to1.label = \'parent\'');
            $any_match = false;
            $parent = array();
            $possible_parents = $this->database->loadAssocList();
            foreach ($possible_parents as $par) {
                if (isset($map[$par['tag']])) {
                    $parent[] = $par;
                    $any_match = true;
                }
            }
            if (!$possible_parents || $any_match) {
                $filtered[] = $tag;
                $parent_id = array();
                foreach ($parent as $par) {
                    $parent_id[] = $par['id'];
                }
                if (isset($fas[$tag[2]]) && $fas[$tag[2]]['actual_depth'] < $fas[$tag[2]]['minimum_depth']) {
                    // count depth if necessary to determine whether focus area constraints are satisified
                    for ($depth = $parent ? 2 : 1; $parent_id && $fas[$tag[2]]['actual_depth'] < $fas[$tag[2]]['minimum_depth'] && $depth < $fas[$tag[2]]['minimum_depth']; ++$depth) {
                        $this->database->setQuery('SELECT t.id
							FROM #__tags_object to1
							INNER JOIN #__tags t ON t.id = to1.tagid
							INNER JOIN #__tags_object to2 ON to2.tagid = ' . $tag[4] . ' AND to2.tbl = \'tags\' AND to2.objectid = to1.tagid
							WHERE to1.objectid IN (' . implode(',', $parent_id) . ') AND to1.tbl = \'tags\' AND to1.label = \'parent\'');
                        $parent_id = $this->database->loadColumn();
                    }
                    $fas[$tag[2]]['actual_depth'] = max($depth, $fas[$tag[2]]['actual_depth']);
                }
            } else {
                unset($map[$tag[1]]);
            }
        }
        $push = $filtered;
        foreach ($tags as $tag) {
            $norm_tag = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tag));
            if (!$norm_tag || isset($map[$norm_tag])) {
                continue;
            }
            $push[] = array($tag, $norm_tag, null);
            $map[$norm_tag] = true;
        }
        foreach ($push as $idx => $tag) {
            $this->database->setQuery("SELECT raw_tag FROM `#__tags` WHERE tag = " . $this->database->quote($tag[1]));
            if ($raw_tag = $this->database->loadResult()) {
                $push[$idx][0] = $raw_tag;
            }
        }
        foreach ($fas as $lbl => $fa) {
            if ($fa['actual_depth'] < $fa['minimum_depth']) {
                $this->setError($fa['minimum_depth'] == 1 ? 'Please ensure you have made a ' . $lbl . ' selection' : 'Please make selections for "' . $lbl . '" to a depth of at least ' . $fa['minimum_depth']);
                --$this->step;
                $this->view->step = $this->step;
                $this->view->setLayout('tags');
                return $this->step_tags($push);
            }
        }
        $tags = array();
        foreach ($push as $tag) {
            $tags[] = $tag[0];
        }
        $tags = implode(', ', $tags);
        $rt = new Tags($id);
        $this->database->setQuery('DELETE FROM `#__tags_object` WHERE tbl = \'resources\' AND objectid = ' . $id);
        $this->database->execute();
        foreach ($push as $tag) {
            $rt->add($tag[0], User::get('id'), 0, 1, $tag[2] ? $tag[2] : '');
        }
    }