root/taggingreloaded/files/lib/util/TaggingReloadedUtil.class.php @ 1195

Revision 1195, 9.2 kB (checked in by d0nut, 3 years ago)

added negative list

Line 
1<?php
2require_once(WCF_DIR.'/lib/util/TaggingUtil.class.php');
3require_once(WCF_DIR.'/lib/util/ArrayUtil.class.php');
4require_once(WCF_DIR.'/lib/util/StringUtil.class.php');
5require_once(WCF_DIR.'lib/data/tag/Tag.class.php');
6require_once(WCF_DIR.'lib/data/tag/TagCloudWrapper.class.php');
7require_once(WCF_DIR.'lib/data/tag/TagEngine.class.php');
8
9/**
10 * Util for Tagging Operations
11 *
12 * @author      Torben Brodt
13 * @package     de.easy-coding.wcf.taggingreloaded
14 * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-3.0.html>
15 */
16class TaggingReloadedUtil {
17        public static function readFormParameters() {
18                $tags3 = array();
19
20                // handle reloaded input
21                if (isset($_REQUEST['taggingname']) && isset($_REQUEST['taggingval'])) {
22                        if(count($_REQUEST['taggingname']) > count($_REQUEST['taggingval'])) {
23                                $_REQUEST['taggingval'] = array_slice($_REQUEST['taggingval'], 0, count($_REQUEST['taggingname']));
24                        } else if(count($_REQUEST['taggingname']) < count($_REQUEST['taggingval'])) {
25                                $_REQUEST['taggingname'] = array_slice($_REQUEST['taggingname'], 0, count($_REQUEST['taggingval']));
26                        }
27                        $tags3 = array_combine($_REQUEST['taggingname'], $_REQUEST['taggingval']);
28                }
29
30                // handle classic input
31                if (!isset($_REQUEST['wheeltags_enabled']) || !($_REQUEST['wheeltags_enabled'])) {
32                        // copy reference
33                        $tags = $tags3;
34                        $tags3 = array();
35                       
36                        // proceed with classic
37                        if (isset($_REQUEST['tags']) && !empty($_REQUEST['tags'])) {
38                                foreach(TaggingUtil::splitString($_REQUEST['tags']) as $tag) {
39                                        // use weights from modern input (even if hidden)
40                                        if(array_key_exists($tag, $tags)) {
41                                                $tags3[$tag] = $tags[$tag];
42                                        } else if(array_key_exists($tag, $tags3)) {
43                                                $tags3[$tag] *= 1.33; // increase with 33%
44                                        } else {
45                                                $tags3[$tag] = 100;
46                                        }
47                                }
48                        }
49                }
50               
51                // conversion from post to Tag
52                foreach($tags3 as $name => $weight) {
53                        if(strlen($name) < 3) {
54                                unset($tags3[$name]);
55                                continue;
56                        }
57
58                        $tags3[$name] = new Tag(null, array(
59                                'name' => $name,
60                                'weight' => $weight
61                        ));
62                }
63               
64                return $tags3;
65        }
66       
67        protected static function deleteFromTagging3($userID, $tags, Tagged $object, $languageIDArray) {
68                if(!count($tags)) return;
69               
70                $ids = array();
71                foreach($tags as $tag) {
72                        $ids[] = $tag->tagID;
73                }
74               
75                $sql = "DELETE FROM     wcf".WCF_N."_tagging3
76                        WHERE           taggableID = ".$object->getTaggable()->getTaggableID()."
77                                        AND languageID IN (".implode(',', $languageIDArray).")
78                                        AND objectID = ".$object->getObjectID()."
79                                        AND tagID IN (".implode(",", $ids).")
80                                        AND userID = ".intval($userID);
81                WCF::getDB()->sendQuery($sql);
82                $result = WCF::getDB()->sendQuery($sql);
83        }
84       
85        /**
86         * this is a reimplemenation of TagEngine::deleteObjectTags with a slite modification.
87         * not all tags are deleted. just some tagIDs
88         */
89        protected static function deleteFromSystem($tags, Tagged $object, $languageIDArray) {
90                if(!count($tags)) return;
91               
92                $ids = array();
93                foreach($tags as $tag) {
94                        $ids[] = $tag->tagID;
95                }
96               
97                $sql = "DELETE FROM     wcf".WCF_N."_tag_to_object
98                        WHERE           taggableID = ".$object->getTaggable()->getTaggableID()."
99                                        AND languageID IN (".implode(',', $languageIDArray).")
100                                        AND objectID = ".$object->getObjectID()."
101                                        AND tagID IN (".implode(",", $ids).")";
102                WCF::getDB()->sendQuery($sql);
103                $result = WCF::getDB()->sendQuery($sql);
104        }
105       
106        protected static function addToSystem($tags, Tagged $object, $languageID) {
107                if(!count($tags)) return;
108               
109                $tags = array_keys($tags);
110                try {
111                        TagEngine::getInstance()->addTags($tags, $object, $languageID);
112                } catch(Exception $e) {
113                        // please handle
114                }
115        }
116       
117        /**
118         * this is a reimplementation of TagEngine::addTags with a slite modification to write to our table and to update existing tables with weight
119         */
120        protected static function addToTagging3($userID, $tags, Tagged $object, $languageID) {
121                if(!count($tags)) return;
122               
123                // store tagging3 database
124                $tagIDs = array();
125                foreach ($tags as $tag) {
126                        $tagID = $tag->tagID ? $tag->tagID : Tag::test($tag->name, $languageID);
127                        if (!$tagID) $tagID = Tag::insert($tag->name, $languageID);
128                       
129                        if (empty($tag->userID)) $tag->userID = $userID;
130                        $tagIDs[$tagID] = $tag;
131                }
132               
133                $sql = "REPLACE INTO    wcf".WCF_N."_tagging3
134                                        (objectID, tagID, taggableID, languageID, userID, weight)
135                        VALUES ";
136                foreach ($tagIDs as $tagID => $tag) {
137                        $sql .= "(" . $object->getObjectID() . ", " . $tagID . ", " . $object->getTaggable()->getTaggableID() . ",
138                                ".$languageID.", ".$tag->userID.", ".$tag->weight."),";
139                }
140                $sql = StringUtil::substring($sql, 0, StringUtil::length($sql) - 1);
141                $result = WCF::getDB()->sendQuery($sql);
142        }
143       
144        /**
145         * save
146         */
147        public static function tagging3Save($userID, $tagged, $languageID, array $tags3, array $existingTagsUser = array(), array $existingTagsObject = array()) {
148                $languageIDArray = array($languageID);
149               
150                // remove old links
151                if(count($existingTagsUser) || count($existingTagsObject)) {
152               
153                        // tagging3: remove the link to the current user
154                        $deleteFromTagging3 = TaggingReloadedUtil::diff($existingTagsUser, $tags3);
155               
156                        // woltlab system: when no other user has this tag, remove the link from tag to object
157                        $deleteFromSystem = TaggingReloadedUtil::diff($deleteFromTagging3, $existingTagsObject);
158                       
159                        // tagging3: ids are known.. delete is easy
160                        self::deleteFromTagging3($userID, $deleteFromTagging3, $tagged, $languageIDArray);
161                       
162                        // woltlab system: ids are known.. delete is easy
163                        self::deleteFromSystem($deleteFromSystem, $tagged, $languageIDArray);
164                }
165               
166                // tagging3: add user specific tags
167                $addToTagging3 = TaggingReloadedUtil::diff($tags3, $existingTagsUser);
168               
169                // woltlab system: add link from tag to object
170                $addToSystem = TaggingReloadedUtil::diff($addToTagging3, $existingTagsObject);
171               
172                // woltlab system: save
173                self::addToSystem($addToSystem, $tagged, $languageID);
174               
175                // tagging3: save
176                // attention: use $tags3 instead of the diff, because we want to update all weights
177                self::addToTagging3($userID, $tags3, $tagged, $languageID);
178        }
179
180        /**
181         * @return Tag[]
182         */
183        public static function getTagsByObject($userID, Tagged $tagged, $languageID, $even = true) {
184                $taggableID = $tagged->getTaggable()->getTaggableID();
185                $objectID = $tagged->getObjectID();
186               
187                $sign = $even ? '=' : '!=';
188                $signline = $even === null ? '' : "AND userID $sign ".intval($userID);
189       
190                $sql = "SELECT          tag.*,
191                                        userID,
192                                        weight
193                        FROM (
194                                SELECT          tagID,
195                                                userID,
196                                                weight
197                                FROM            wcf".WCF_N."_tagging3
198                                WHERE           taggableID = ".intval($taggableID)."
199                                AND             languageID = ".intval($languageID)."
200                                AND             objectID = ".intval($objectID)."
201                                ".$signline."
202                        ) x
203                        INNER JOIN      wcf".WCF_N."_tag tag USING(tagID)
204                        ";
205                $result = WCF::getDB()->sendQuery($sql);
206                $tags = array();
207                while ($row = WCF::getDB()->fetchArray($result)) {
208                        $tags[$row['name']] = new Tag(null, $row);
209                }
210                return $tags;
211        }
212
213        /**
214         * gets possible tags depending on rewrite rules
215         *
216         * @param       string          $name
217         */
218        public static function getPossibleFromRewritten($name) {
219                // try with "-" and without
220                if(strpos($name, '-') !== null) {
221                        $names[] = str_replace('-', ' ', $name);
222                }
223               
224                // try umlauts
225                $umlauts = array(
226                        'ae' => 'À',
227                        'oe' => 'ö',
228                        'ue' => 'ÃŒ',
229                        'ß' => 'ss',
230                );
231                if(preg_match('/('.implode('|', array_keys($umlauts)).')/', $name)) {
232                        $names[] = str_replace(array_keys($umlauts), $umlauts, $name);
233                }
234                return $names;
235        }
236
237        /**
238         * returns difference between two lists full of tag objects
239         *
240         * @param       array<Tag>      $list1
241         * @param       array<Tag>      $list2
242         */
243        public static function diff($list1, $list2) {
244                $diff = array_diff(array_keys($list1), array_keys($list2));
245                foreach($list1 as $key => $val) {
246                        if(!in_array($key, $diff)) {
247                                unset($list1[$key]);
248                        }
249                }
250                return $list1;
251        }
252       
253        /**
254         * begins with biggest value
255         */
256        public static function sort($result, $column = 'counter', $sort = 'ASC') {
257                uasort($result, "TaggingReloadedUtil::sort".ucfirst($column));
258                if($sort == 'DESC') {
259                        arsort($result);
260                }
261                return $result;
262        }
263       
264        public static function sortCounter($a, $b) {
265                $key = 'counter';
266                if ($a->$key == $b->$key) {
267                        return 0;
268                }
269                return ($a->$key > $b->$key) ? 1 : -1;
270        }
271       
272        public static function sortName($a, $b) {
273                $key = 'name';
274                if ($a->$key == $b->$key) {
275                        return 0;
276                }
277                return ($a->$key > $b->$key) ? 1 : -1;
278        }
279       
280        /**
281         *
282         */
283        public static function fromMagicString($query) {
284                $list = array();
285
286                // clean
287                $query = preg_replace('/(site:[^ ]+)/', '', $query);
288                $query = str_replace('\\', '', $query);
289               
290                // aggregated
291                if(preg_match_all('/"([^"]+)"|\'([^"]+)\'/', $query, $match)) {
292                        $list = array_merge($match[1], $match[2]);
293                        $list = array_filter($list);
294                        $query = str_replace($match[0], ' ', $query);
295                }
296               
297                // c++
298                $query = preg_replace('/[Cc]\+\+/', 'cpp', $query);
299                $query = preg_replace('/[\(\)\+\/]/', ' ', $query);
300               
301                $list2 = TaggingUtil::splitString($query, ',. ');
302                $list = array_merge($list, $list2);
303               
304                $negative_file = dirname(__FILE__).'/negative.list';
305                if(file_exists($negative_file)) {
306                        $negative = file($negative_file);
307                        $negative = array_map("StringUtil::trim", $negative);
308                        $list = array_diff($list, $negative);
309                }
310
311                $arr = array();
312                foreach($list as $tag) {
313                        $arr[$tag] = new Tag(null, array(
314                                'name' => $tag
315                        ));
316                }
317               
318                return $arr;
319        }
320}
321?>
Note: See TracBrowser for help on using the browser.