--- /dev/null
+OC.Tags= {
+ edit:function(type, cb) {
+ if(!type && !this.type) {
+ throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
+ }
+ type = type ? type : this.type;
+ var self = this;
+ $.when(this._getTemplate()).then(function($tmpl) {
+ if(self.$dialog) {
+ self.$dialog.ocdialog('close');
+ }
+ self.$dialog = $tmpl.octemplate({
+ addText: t('core', 'Enter new')
+ });
+ $('body').append(self.$dialog);
+
+ self.$dialog.ready(function() {
+ self.$taglist = self.$dialog.find('.taglist');
+ self.$taginput = self.$dialog.find('.addinput');
+ self.$taglist.on('change', 'input:checkbox', function(event) {
+ self._handleChanges(self.$taglist, self.$taginput);
+ });
+ self.$taginput.on('input', function(event) {
+ self._handleChanges(self.$taglist, self.$taginput);
+ });
+ self.deleteButton = {
+ text: t('core', 'Delete'),
+ click: function() {self._deleteTags(self, type, self._selectedIds())},
+ };
+ self.addButton = {
+ text: t('core', 'Add'),
+ click: function() {self._addTag(self, type, self.$taginput.val())},
+ };
+
+ self._fillTagList(type, self.$taglist);
+ });
+
+ self.$dialog.ocdialog({
+ title: t('core', 'Edit tags'),
+ closeOnEscape: true,
+ width: 250,
+ height: 'auto',
+ modal: true,
+ //buttons: buttonlist,
+ close: function(event, ui) {
+ try {
+ $(this).ocdialog('destroy').remove();
+ } catch(e) {console.warn(e);}
+ self.$dialog = null;
+ }
+ });
+ })
+ .fail(function(status, error) {
+ // If the method is called while navigating away
+ // from the page, it is probably not needed ;)
+ if(status !== 0) {
+ alert(t('core', 'Error loading dialog template: {error}', {error: error}));
+ }
+ });
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of ids
+ */
+ getIdsForTag:function(type, tag) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_ids_for_tag', {type: type});
+ $.getJSON(url, {tag: tag}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.ids);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of ids
+ */
+ getFavorites:function(type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_favorites', {type: type});
+ $.getJSON(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.ids);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of id/name objects
+ */
+ getTags:function(type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_tags', {type: type});
+ $.getJSON(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.tags);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ tagAs:function(id, tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_tag', {type: type, id: id});
+ $.post(url, {tag: tag}, function(response) {
+ if(response.result === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ unTag:function(id, tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_untag', {type: type, id: id});
+ $.post(url, {tag: tag}, function(response) {
+ if(response.result === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ addToFavorites:function(id, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_favorite', {type: type, id: id});
+ $.post(url, function(response) {
+ if(response.result === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ removeFromFavorites:function(id, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_unfavorite', {type: type, id: id});
+ $.post(url, function(response) {
+ if(response.result === 'success') {
+ defer.resolve();
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string tag
+ * @param string type
+ * @return jQuery.Promise which resolves with an object with the name and the new id
+ */
+ addTag:function(tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_add', {type: type});
+ $.post(url,{tag:tag}, function(response) {
+ if(typeof cb == 'function') {
+ cb(response);
+ }
+ if(response.status === 'success') {
+ defer.resolve({id:response.id, name: tag});
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param array tags
+ * @param string type
+ * @return jQuery.Promise
+ */
+ deleteTags:function(tags, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_delete', {type: type});
+ if(!tags || !tags.length) {
+ throw new Error(t('core', 'No tags selected for deletion.'));
+ }
+ var self = this;
+ $.post(url, {tags:tags}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.tags);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ _update:function(tags, type) {
+ if(!this.$dialog) {
+ return;
+ }
+ var $taglist = this.$dialog.find('.taglist'),
+ self = this;
+ $taglist.empty();
+ $.each(tags, function(idx, tag) {
+ var $item = self.$listTmpl.octemplate({id: tag.id, name: tag.name});
+ $item.appendTo($taglist);
+ });
+ $(this).trigger('change', {type: type, tags: tags});
+ if(typeof this.changed === 'function') {
+ this.changed(tags);
+ }
+ },
+ _getTemplate: function() {
+ var defer = $.Deferred();
+ if(!this.$template) {
+ var self = this;
+ $.get(OC.filePath('core', 'templates', 'tags.html'), function(tmpl) {
+ self.$template = $(tmpl);
+ self.$listTmpl = self.$template.find('.taglist li:first-child').detach();
+ defer.resolve(self.$template);
+ })
+ .fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ } else {
+ defer.resolve(this.$template);
+ }
+ return defer.promise();
+ },
+ _fillTagList: function(type) {
+ var self = this;
+ $.when(this.getTags(type))
+ .then(function(tags) {
+ self._update(tags, type);
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ },
+ _selectedIds: function() {
+ return $.map(this.$taglist.find('input:checked'), function(b) {return $(b).val();});
+ },
+ _handleChanges: function($list, $input) {
+ var ids = this._selectedIds();
+ var buttons = [];
+ if($input.val().length) {
+ buttons.push(this.addButton);
+ }
+ if(ids.length) {
+ buttons.push(this.deleteButton);
+ }
+ this.$dialog.ocdialog('option', 'buttons', buttons);
+ },
+ _deleteTags: function(self, type, ids) {
+ $.when(self.deleteTags(ids, type))
+ .then(function() {
+ self._fillTagList(type);
+ self.$dialog.ocdialog('option', 'buttons', []);
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ },
+ _addTag: function(self, type, tag) {
+ $.when(self.addTag(tag, type))
+ .then(function(tag) {
+ self._fillTagList(type);
+ self.$taginput.val('').trigger('input');
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ }
+}
+
// Translations
$this->create('core_ajax_translations', '/core/ajax/translations.php')
->actionInclude('core/ajax/translations.php');
-// VCategories
-$this->create('core_ajax_vcategories_add', '/core/ajax/vcategories/add.php')
- ->actionInclude('core/ajax/vcategories/add.php');
-$this->create('core_ajax_vcategories_delete', '/core/ajax/vcategories/delete.php')
- ->actionInclude('core/ajax/vcategories/delete.php');
-$this->create('core_ajax_vcategories_addtofavorites', '/core/ajax/vcategories/addToFavorites.php')
- ->actionInclude('core/ajax/vcategories/addToFavorites.php');
-$this->create('core_ajax_vcategories_removefromfavorites', '/core/ajax/vcategories/removeFromFavorites.php')
- ->actionInclude('core/ajax/vcategories/removeFromFavorites.php');
-$this->create('core_ajax_vcategories_favorites', '/core/ajax/vcategories/favorites.php')
- ->actionInclude('core/ajax/vcategories/favorites.php');
-$this->create('core_ajax_vcategories_edit', '/core/ajax/vcategories/edit.php')
- ->actionInclude('core/ajax/vcategories/edit.php');
+// Tags
+$this->create('core_tags_tags', '/tags/{type}')
+ ->get()
+ ->action('OC\Core\Tags\Controller', 'getTags')
+ ->requirements(array('type'));
+$this->create('core_tags_favorites', '/tags/{type}/favorites')
+ ->get()
+ ->action('OC\Core\Tags\Controller', 'getFavorites')
+ ->requirements(array('type'));
+$this->create('core_tags_ids_for_tag', '/tags/{type}/ids')
+ ->get()
+ ->action('OC\Core\Tags\Controller', 'getIdsForTag')
+ ->requirements(array('type'));
+$this->create('core_tags_favorite', '/tags/{type}/favorite/{id}/')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'favorite')
+ ->requirements(array('type', 'id'));
+$this->create('core_tags_unfavorite', '/tags/{type}/infavorite/{id}/')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'unFavorite')
+ ->requirements(array('type', 'id'));
+$this->create('core_tags_tag', '/tags/{type}/tag/{id}/')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'tagAs')
+ ->requirements(array('type', 'id'));
+$this->create('core_tags_untag', '/tags/{type}/untag/{id}/')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'unTag')
+ ->requirements(array('type', 'id'));
+$this->create('core_tags_add', '/tags/{type}/add')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'addTag')
+ ->requirements(array('type'));
+$this->create('core_tags_delete', '/tags/{type}/delete')
+ ->post()
+ ->action('OC\Core\Tags\Controller', 'deleteTags')
+ ->requirements(array('type'));
// oC JS config
$this->create('js_config', '/core/js/config.js')
->actionInclude('core/js/config.php');
--- /dev/null
+<?php
+/**
+ * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Core\Tags;
+
+class Controller {
+ protected static function getTagger($type) {
+ \OC_JSON::checkLoggedIn();
+ \OC_JSON::callCheck();
+
+ try {
+ $tagger = \OC::$server->getTagManager()->load($type);
+ return $tagger;
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__ . ' Exception: ' . $e->getMessage(), \OCP\Util::ERROR);
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error loading tags')));
+ exit;
+ }
+ }
+
+ public static function getTags($args) {
+ $tagger = self::getTagger($args['type']);
+ \OC_JSON::success(array('tags'=> $tagger->getTags()));
+ }
+
+ public static function getFavorites($args) {
+ $tagger = self::getTagger($args['type']);
+ \OC_JSON::success(array('ids'=> $tagger->getFavorites()));
+ }
+
+ public static function getIdsForTag($args) {
+ $tagger = self::getTagger($args['type']);
+ \OC_JSON::success(array('ids'=> $tagger->getIdsForTag($_GET['tag'])));
+ }
+
+ public static function addTag($args) {
+ $tagger = self::getTagger($args['type']);
+
+ $id = $tagger->add(strip_tags($_POST['tag']));
+ if($id === false) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Tag already exists')));
+ } else {
+ \OC_JSON::success(array('id'=> $id));
+ }
+ }
+
+ public static function deleteTags($args) {
+ $tags = $_POST['tags'];
+ if(!is_array($tags)) {
+ $tags = array($tags);
+ }
+
+ $tagger = self::getTagger($args['type']);
+
+ if(!$tagger->delete($tags)) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error deleting tag(s)')));
+ } else {
+ \OC_JSON::success();
+ }
+ }
+
+ public static function tagAs($args) {
+ $tagger = self::getTagger($args['type']);
+
+ if(!$tagger->tagAs($args['id'], $_POST['tag'])) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error tagging')));
+ } else {
+ \OC_JSON::success();
+ }
+ }
+
+ public static function unTag($args) {
+ $tagger = self::getTagger($args['type']);
+
+ if(!$tagger->unTag($args['id'], $_POST['tag'])) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error untagging')));
+ } else {
+ \OC_JSON::success();
+ }
+ }
+
+ public static function favorite($args) {
+ $tagger = self::getTagger($args['type']);
+
+ if(!$tagger->addToFavorites($args['id'])) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error favoriting')));
+ } else {
+ \OC_JSON::success();
+ }
+ }
+
+ public static function unFavorite($args) {
+ $tagger = self::getTagger($args['type']);
+
+ if(!$tagger->removeFromFavorites($args['id'])) {
+ $l = new \OC_L10n('core');
+ \OC_JSON::error(array('message'=> $l->t('Error unfavoriting')));
+ } else {
+ \OC_JSON::success();
+ }
+ }
+
+}