root/taggingreloaded/files/lib/system/event/listener/TaggingReloadedMessageFormListener.class.php @ 1079

Revision 1079, 8.5 kB (checked in by d0nut, 4 years ago)

bugfix release to 0.8.1

Line 
1<?php
2// wcf imports
3require_once(WCF_DIR.'lib/system/event/EventListener.class.php');
4require_once(WCF_DIR.'lib/data/tag/Tag.class.php');
5require_once(WCF_DIR.'lib/data/tag/TagEngine.class.php');
6
7// tagging3 imports
8require_once(WCF_DIR.'lib/util/TaggingReloadedUtil.class.php');
9
10/**
11 * Displays the tab for tagging - this is base for wbb tagging reloaded message form listener
12 *
13 * @author      Torben Brodt
14 * @package     de.easy-coding.wcf.taggingreloaded
15 * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-3.0.html>
16 */
17class TaggingReloadedMessageFormListener implements EventListener {
18        protected $eventObj;
19        protected $className;
20        protected $tags3 = array();
21       
22        /**
23         * @var Tag[]
24         */
25        protected $existingTagsUser = array();
26
27        /**
28         * @var Tag[]
29         */
30        protected $existingTagsObject = array();
31
32        /**
33         * @see EventListener::execute()
34         */
35        public function execute($eventObj, $className, $eventName) {
36
37                // enabled?             
38                if(!MODULE_TAGGING) {
39                        return;
40                }
41
42                $this->eventObj = $eventObj;
43                $this->className = $className;
44               
45                if(method_exists($this, $eventName)) {
46                        $this->$eventName();
47                }
48        }
49
50        /**
51         * @see Form::assignVariables()
52         */
53        protected function assignVariables () {
54                WCF::getTPL()->assign(array(
55                        'tags3' => $this->tags3,
56                        'tags' => $this->eventObj->tags
57                ));
58
59                WCF::getTPL()->append('specialStyles', '<script type="text/javascript" src="'.RELATIVE_WCF_DIR.'js/Wheeltags.class.js"></script>');
60                WCF::getTPL()->append('additionalInformationFields', WCF::getTPL()->fetch('messageFormTaggingReloaded'));
61        }
62       
63        /**
64         * @see Form::readFormParameters()
65         */
66        protected function readFormParameters() {
67       
68                // handle reloaded input
69                if (isset($_REQUEST['taggingname']) && isset($_REQUEST['taggingval'])) {
70                        if(count($_REQUEST['taggingname']) > count($_REQUEST['taggingval'])) {
71                                $_REQUEST['taggingval'] = array_slice($_REQUEST['taggingval'], 0, count($_REQUEST['taggingname']));
72                        } else if(count($_REQUEST['taggingname']) < count($_REQUEST['taggingval'])) {
73                                $_REQUEST['taggingname'] = array_slice($_REQUEST['taggingname'], 0, count($_REQUEST['taggingval']));
74                        }
75                        $this->tags3 = array_combine($_REQUEST['taggingname'], $_REQUEST['taggingval']);
76                }
77
78                // handle classic input
79                if (!isset($_REQUEST['wheeltags_enabled']) || !($_REQUEST['wheeltags_enabled'])) {
80                        // copy reference
81                        $tags3 = $this->tags3;
82                        $this->tags3 = array();
83                       
84                        // proceed with classic
85                        if (isset($_REQUEST['tags']) && !empty($_REQUEST['tags'])) {
86                                foreach(TaggingUtil::splitString($_REQUEST['tags']) as $tag) {
87                                        // use weights from modern input (even if hidden)
88                                        if(array_key_exists($tag, $tags3)) {
89                                                $this->tags3[$tag] = $tags3[$tag];
90                                        } else if(array_key_exists($tag, $this->tags3)) {
91                                                $this->tags3[$tag] *= 1.33; // increase with 33%
92                                        } else {
93                                                $this->tags3[$tag] = 100;
94                                        }
95                                }
96                        }
97                }
98               
99                // conversion from post to Tag
100                foreach($this->tags3 as $name => $weight) {
101                        if(strlen($name) < 3) {
102                                unset($this->tags3[$name]);
103                                continue;
104                        }
105
106                        $this->tags3[$name] = new Tag(null, array(
107                                'name' => $name,
108                                'weight' => $weight
109                        ));
110                }
111               
112                // workaround to be called before validate from woltlab
113                $this->eventObj->tags = TaggingUtil::buildString(array_keys($this->tags3));
114        }
115       
116        /**
117         * workaround to be called after readFormData from woltlab
118         * @see Form::validate()
119         */
120        protected function validate () {
121                $this->eventObj->tags = TaggingUtil::buildString(array_keys($this->tags3));
122        }
123       
124        public function deleteFromTagging3($userID, $tags, Tagged $object, $languageIDArray) {
125                if(!count($tags)) return;
126               
127                $ids = array();
128                foreach($tags as $tag) {
129                        $ids[] = $tag->tagID;
130                }
131               
132                $sql = "DELETE FROM     wcf".WCF_N."_tagging3
133                        WHERE           taggableID = ".$object->getTaggable()->getTaggableID()."
134                                        AND languageID IN (".implode(',', $languageIDArray).")
135                                        AND objectID = ".$object->getObjectID()."
136                                        AND tagID IN (".implode(",", $ids).")
137                                        AND userID = ".intval($userID);
138                WCF::getDB()->sendQuery($sql);
139                $result = WCF::getDB()->sendQuery($sql);
140        }
141       
142        /**
143         * this is a reimplemenation of TagEngine::deleteObjectTags with a slite modification.
144         * not all tags are deleted. just some tagIDs
145         */
146        public function deleteFromSystem($tags, Tagged $object, $languageIDArray) {
147                if(!count($tags)) return;
148               
149                $ids = array();
150                foreach($tags as $tag) {
151                        $ids[] = $tag->tagID;
152                }
153               
154                $sql = "DELETE FROM     wcf".WCF_N."_tag_to_object
155                        WHERE           taggableID = ".$object->getTaggable()->getTaggableID()."
156                                        AND languageID IN (".implode(',', $languageIDArray).")
157                                        AND objectID = ".$object->getObjectID()."
158                                        AND tagID IN (".implode(",", $ids).")";
159                WCF::getDB()->sendQuery($sql);
160                $result = WCF::getDB()->sendQuery($sql);
161        }
162       
163        public function addToSystem($tags, Tagged $object, $languageID) {
164                if(!count($tags)) return;
165               
166                $tags = array_keys($tags);
167                try {
168                        TagEngine::getInstance()->addTags($tags, $object, $languageID);
169                } catch(Exception $e) {
170                        // please handle
171                }
172        }
173       
174        /**
175         * this is a reimplementation of TagEngine::addTags with a slite modification to write to our table and to update existing tables with weight
176         */
177        public function addToTagging3($userID, $tags, Tagged $object, $languageID) {
178                if(!count($tags)) return;
179               
180                // store tagging3 database
181                $tagIDs = array();
182                foreach ($tags as $tag) {
183                        $tagID = $tag->tagID ? $tag->tagID : Tag::test($tag->name, $languageID);
184                        if (!$tagID) $tagID = Tag::insert($tag->name, $languageID);
185                       
186                        if (empty($tag->userID)) $tag->userID = $userID;
187                        $tagIDs[$tagID] = $tag;
188                }
189               
190                $sql = "REPLACE INTO    wcf".WCF_N."_tagging3
191                                        (objectID, tagID, taggableID, languageID, userID, weight)
192                        VALUES ";
193                foreach ($tagIDs as $tagID => $tag) {
194                        $sql .= "(" . $object->getObjectID() . ", " . $tagID . ", " . $object->getTaggable()->getTaggableID() . ",
195                                ".$languageID.", ".$tag->userID.", ".$tag->weight."),";
196                }
197                $sql = StringUtil::substring($sql, 0, StringUtil::length($sql) - 1);
198                $result = WCF::getDB()->sendQuery($sql);
199        }
200       
201        /**
202         * save
203         */
204        protected function tagging3Save($userID, $tagged, $languageID) {
205                $languageIDArray = array($languageID);
206               
207                // remove old links
208                if(count($this->existingTagsUser) || count($this->existingTagsObject)) {
209               
210                        // tagging3: remove the link to the current user
211                        $deleteFromTagging3 = TaggingReloadedUtil::diff($this->existingTagsUser, $this->tags3);
212               
213                        // woltlab system: when no other user has this tag, remove the link from tag to object
214                        $deleteFromSystem = TaggingReloadedUtil::diff($deleteFromTagging3, $this->existingTagsObject);
215                       
216                        // tagging3: ids are known.. delete is easy
217                        $this->deleteFromTagging3($userID, $deleteFromTagging3, $tagged, $languageIDArray);
218                       
219                        // woltlab system: ids are known.. delete is easy
220                        $this->deleteFromSystem($deleteFromSystem, $tagged, $languageIDArray);
221                }
222               
223                // tagging3: add user specific tags
224                $addToTagging3 = TaggingReloadedUtil::diff($this->tags3, $this->existingTagsUser);
225               
226                // woltlab system: add link from tag to object
227                $addToSystem = TaggingReloadedUtil::diff($addToTagging3, $this->existingTagsObject);
228               
229                // woltlab system: save
230                $this->addToSystem($addToSystem, $tagged, $languageID);
231               
232                // tagging3: save
233                // attention: use $this->tags3 instead of the diff, because we want to update all weights
234                $this->addToTagging3($userID, $this->tags3, $tagged, $languageID);
235        }
236       
237        /**
238         * load the existing tags of this user from database right before being saved
239         * in save method, we will watch for for this variable
240         */
241        protected function tagging3Load($userID, $tagged, $languageID) {
242                $this->existingTagsUser = $this->getTagsByObject($userID, $tagged, $languageID, true);
243                $this->existingTagsObject = $this->getTagsByObject($userID, $tagged, $languageID, false);
244        }
245
246        /**
247         * @return Tag[]
248         */
249        protected function getTagsByObject($userID, Tagged $tagged, $languageID, $even = true) {
250                $taggableID = $tagged->getTaggable()->getTaggableID();
251                $objectID = $tagged->getObjectID();
252                $sign = $even ? '=' : '!=';
253       
254                $sql = "SELECT          tag.*,
255                                        userID,
256                                        weight
257                        FROM (
258                                SELECT          tagID,
259                                                userID,
260                                                weight
261                                FROM            wcf".WCF_N."_tagging3
262                                WHERE           taggableID = ".intval($taggableID)."
263                                AND             languageID = ".intval($languageID)."
264                                AND             objectID = ".intval($objectID)."
265                                AND             userID $sign ".intval($userID)."
266                        ) x
267                        INNER JOIN      wcf".WCF_N."_tag tag USING(tagID)
268                        ";
269                $result = WCF::getDB()->sendQuery($sql);
270                $tags = array();
271                while ($row = WCF::getDB()->fetchArray($result)) {
272                        $tags[$row['name']] = new Tag(null, $row);
273                }
274                return $tags;
275        }
276}
277?>
Note: See TracBrowser for help on using the browser.