Merge pull request #5133 from owncloud/js_vcategories_to_tags

Js vcategories to tags
This commit is contained in:
Thomas Tanghus 2013-10-11 04:17:59 -07:00
commit 31714f8871
15 changed files with 534 additions and 512 deletions

View File

@ -1,42 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/add.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/add.php: '.$msg, OC_Log::DEBUG);
}
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
$l = OC_L10N::get('core');
$category = isset($_POST['category']) ? strip_tags($_POST['category']) : null;
$type = isset($_POST['type']) ? $_POST['type'] : null;
if(is_null($type)) {
bailOut($l->t('Category type not provided.'));
}
if(is_null($category)) {
bailOut($l->t('No category to add?'));
}
debug(print_r($category, true));
$categories = new OC_VCategories($type);
if($categories->hasCategory($category)) {
bailOut($l->t('This category already exists: %s', array($category)));
} else {
$categories->add($category, true);
}
OC_JSON::success(array('data' => array('categories'=>$categories->categories())));

View File

@ -1,38 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/addToFavorites.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/addToFavorites.php: '.$msg, OC_Log::DEBUG);
}
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
$l = OC_L10N::get('core');
$id = isset($_POST['id']) ? strip_tags($_POST['id']) : null;
$type = isset($_POST['type']) ? $_POST['type'] : null;
if(is_null($type)) {
bailOut($l->t('Object type not provided.'));
}
if(is_null($id)) {
bailOut($l->t('%s ID not provided.', $type));
}
$categories = new OC_VCategories($type);
if(!$categories->addToFavorites($id, $type)) {
bailOut($l->t('Error adding %s to favorites.', $id));
}
OC_JSON::success();

View File

@ -1,40 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/delete.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/delete.php: '.$msg, OC_Log::DEBUG);
}
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
$l = OC_L10N::get('core');
$type = isset($_POST['type']) ? $_POST['type'] : null;
$categories = isset($_POST['categories']) ? $_POST['categories'] : null;
if(is_null($type)) {
bailOut($l->t('Object type not provided.'));
}
debug('The application using category type "'
. $type
. '" uses the default file for deletion. OC_VObjects will not be updated.');
if(is_null($categories)) {
bailOut($l->t('No categories selected for deletion.'));
}
$vcategories = new OC_VCategories($type);
$vcategories->delete($categories);
OC_JSON::success(array('data' => array('categories'=>$vcategories->categories())));

View File

@ -1,34 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/edit.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/edit.php: '.$msg, OC_Log::DEBUG);
}
OC_JSON::checkLoggedIn();
$l = OC_L10N::get('core');
$type = isset($_GET['type']) ? $_GET['type'] : null;
if(is_null($type)) {
bailOut($l->t('Category type not provided.'));
}
$tmpl = new OCP\Template("core", "edit_categories_dialog");
$vcategories = new OC_VCategories($type);
$categories = $vcategories->categories();
debug(print_r($categories, true));
$tmpl->assign('categories', $categories);
$tmpl->printpage();

View File

@ -1,30 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/addToFavorites.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/addToFavorites.php: '.$msg, OC_Log::DEBUG);
}
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
$type = isset($_GET['type']) ? $_GET['type'] : null;
if(is_null($type)) {
$l = OC_L10N::get('core');
bailOut($l->t('Object type not provided.'));
}
$categories = new OC_VCategories($type);
$ids = $categories->getFavorites($type);
OC_JSON::success(array('ids' => $ids));

View File

@ -1,38 +0,0 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('core', 'ajax/vcategories/removeFromFavorites.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('core', 'ajax/vcategories/removeFromFavorites.php: '.$msg, OC_Log::DEBUG);
}
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
$l = OC_L10N::get('core');
$id = isset($_POST['id']) ? strip_tags($_POST['id']) : null;
$type = isset($_POST['type']) ? $_POST['type'] : null;
if(is_null($type)) {
bailOut($l->t('Object type not provided.'));
}
if(is_null($id)) {
bailOut($l->t('%s ID not provided.', array($type)));
}
$categories = new OC_VCategories($type);
if(!$categories->removeFromFavorites($id, $type)) {
bailOut($l->t('Error removing %s from favorites.', array($id)));
}
OC_JSON::success();

View File

@ -29,6 +29,7 @@
bottom: 0;
display: block;
margin-top: 10px;
width: 100%;
}
.oc-dialog-close {

View File

@ -753,15 +753,21 @@ span.ui-icon {float: left; margin: 3px 7px 30px 0;}
height: 16px;
}
/* ---- CATEGORIES ---- */
#categoryform .scrollarea { position:absolute; left:10px; top:10px; right:10px; bottom:50px; overflow:auto; border:1px solid #ddd; background:#f8f8f8; }
#categoryform .bottombuttons { position:absolute; bottom:10px;}
#categoryform .bottombuttons * { float:left;}
/*#categorylist { border:1px solid #ddd;}*/
#categorylist li { background:#f8f8f8; padding:.3em .8em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; -webkit-transition:background-color 500ms; -moz-transition:background-color 500ms; -o-transition:background-color 500ms; transition:background-color 500ms; }
#categorylist li:hover, #categorylist li:active { background:#eee; }
#category_addinput { width:10em; }
/* ---- TAGS ---- */
#tagsdialog .content {
width: 100%; height: 280px;
}
#tagsdialog .scrollarea {
overflow:auto; border:1px solid #ddd;
width: 100%; height: 240px;
}
#tagsdialog .bottombuttons {
width: 100%; height: 30px;
}
#tagsdialog .bottombuttons * { float:left;}
#tagsdialog .taglist li { background:#f8f8f8; padding:.3em .8em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; -webkit-transition:background-color 500ms; -moz-transition:background-color 500ms; -o-transition:background-color 500ms; transition:background-color 500ms; }
#tagsdialog .taglist li:hover, #tagsdialog .taglist li:active { background:#eee; }
#tagsdialog .addinput { width: 90%; clear: both; }
/* ---- APP SETTINGS ---- */
.popup { background-color:white; border-radius:10px 10px 10px 10px; box-shadow:0 0 20px #888; color:#333; padding:10px; position:fixed !important; z-index:100; }

View File

@ -1,216 +0,0 @@
var OCCategories= {
category_favorites:'_$!<Favorite>!$_',
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;
$('body').append('<div id="category_dialog"></div>');
$('#category_dialog').load(
OC.filePath('core', 'ajax', 'vcategories/edit.php') + '?type=' + type, function(response) {
try {
var jsondata = jQuery.parseJSON(response);
if(response.status == 'error') {
OC.dialogs.alert(response.data.message, t('core', 'Error'));
return;
}
} catch(e) {
var setEnabled = function(d, enable) {
if(enable) {
d.css('cursor', 'default').find('input,button:not(#category_addbutton)')
.prop('disabled', false).css('cursor', 'default');
} else {
d.css('cursor', 'wait').find('input,button:not(#category_addbutton)')
.prop('disabled', true).css('cursor', 'wait');
}
};
var dlg = $('#edit_categories_dialog').dialog({
modal: true,
height: 350, minHeight:200, width: 250, minWidth: 200,
buttons: {
'Close': function() {
$(this).dialog('close');
},
'Delete':function() {
var categories = $('#categorylist').find('input:checkbox').serialize();
setEnabled(dlg, false);
OCCategories.doDelete(categories, function() {
setEnabled(dlg, true);
});
},
'Rescan':function() {
setEnabled(dlg, false);
OCCategories.rescan(function() {
setEnabled(dlg, true);
});
}
},
close : function(event, ui) {
$(this).dialog('destroy').remove();
$('#category_dialog').remove();
},
open : function(event, ui) {
$('#category_addinput').on('input',function() {
if($(this).val().length > 0) {
$('#category_addbutton').removeAttr('disabled');
}
});
$('#categoryform').submit(function() {
OCCategories.add($('#category_addinput').val());
$('#category_addinput').val('');
$('#category_addbutton').attr('disabled', 'disabled');
return false;
});
$('#category_addbutton').on('click',function(e) {
e.preventDefault();
if($('#category_addinput').val().length > 0) {
OCCategories.add($('#category_addinput').val());
$('#category_addinput').val('');
}
});
}
});
}
});
},
_processDeleteResult:function(jsondata) {
if(jsondata.status == 'success') {
OCCategories._update(jsondata.data.categories);
} else {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
},
favorites:function(type, cb) {
if(!type && !this.type) {
throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
}
type = type ? type : this.type;
$.getJSON(OC.filePath('core', 'ajax', 'categories/favorites.php'), {type: type},function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
if(jsondata.status === 'success') {
OCCategories._update(jsondata.data.categories);
} else {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
}
});
},
addToFavorites:function(id, type, cb) {
if(!type && !this.type) {
throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
}
type = type ? type : this.type;
$.post(OC.filePath('core', 'ajax', 'vcategories/addToFavorites.php'), {id:id, type:type}, function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
if(jsondata.status !== 'success') {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
}
});
},
removeFromFavorites:function(id, type, cb) {
if(!type && !this.type) {
throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
}
type = type ? type : this.type;
$.post(OC.filePath('core', 'ajax', 'vcategories/removeFromFavorites.php'), {id:id, type:type}, function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
if(jsondata.status !== 'success') {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
}
});
},
doDelete:function(categories, type, cb) {
if(!type && !this.type) {
throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
}
type = type ? type : this.type;
if(categories == '' || categories == undefined) {
OC.dialogs.alert(t('core', 'No categories selected for deletion.'), t('core', 'Error'));
return false;
}
var self = this;
var q = categories + '&type=' + type;
if(this.app) {
q += '&app=' + this.app;
$.post(OC.filePath(this.app, 'ajax', 'categories/delete.php'), q, function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
self._processDeleteResult(jsondata);
}
});
} else {
$.post(OC.filePath('core', 'ajax', 'vcategories/delete.php'), q, function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
self._processDeleteResult(jsondata);
}
});
}
},
add:function(category, type, cb) {
if(!type && !this.type) {
throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
}
type = type ? type : this.type;
$.post(OC.filePath('core', 'ajax', 'vcategories/add.php'),{'category':category, 'type':type},function(jsondata) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
if(jsondata.status === 'success') {
OCCategories._update(jsondata.data.categories);
} else {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
}
});
},
rescan:function(app, cb) {
if(!app && !this.app) {
throw { name: 'MissingParameter', message: t('core', 'The app name is not specified.') };
}
app = app ? app : this.app;
$.getJSON(OC.filePath(app, 'ajax', 'categories/rescan.php'),function(jsondata, status, xhr) {
if(typeof cb == 'function') {
cb(jsondata);
} else {
if(jsondata.status === 'success') {
OCCategories._update(jsondata.data.categories);
} else {
OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
}
}
}).error(function(xhr){
if (xhr.status == 404) {
var errormessage = t('core', 'The required file {file} is not installed!',
{file: OC.filePath(app, 'ajax', 'categories/rescan.php')}, t('core', 'Error'));
if(typeof cb == 'function') {
cb({status:'error', data:{message:errormessage}});
} else {
OC.dialogs.alert(errormessage, t('core', 'Error'));
}
}
});
},
_update:function(categories) {
var categorylist = $('#categorylist');
categorylist.find('li').remove();
for(var category in categories) {
var item = '<li><input type="checkbox" name="categories" value="' + categories[category] + '" />' + categories[category] + '</li>';
$(item).appendTo(categorylist);
}
if(typeof OCCategories.changed === 'function') {
OCCategories.changed(categories);
}
}
}

View File

@ -1,33 +0,0 @@
Using OCCategories
This 'class' is meant for any apps that uses OC_VObjects with the CATEGORIES field e.g.
Contacts and Calendar. It provides an editor UI for adding/deleting and rescanning categories
and basic ajax functions for adding and deleting.
To use the mass updating of OC_VObjects that /lib/vcategories.php provides, the app must implement
its own ajax functions in /apps/$(APP)/ajax/categories/rescan.php and /apps/$(APP)/ajax/categories/delete.php
See examples in /apps/contacts/ajax/categories and the inline docs in /lib/vcategories.php.
In your app make sure you load the script and stylesheet:
OC_Util::addScript('','oc-vcategories');
OC_Util::addStyle('','oc-vcategories');
Set the app specific values in your javascript file. This is what I've used for the Contacts app:
OCCategories.app = 'contacts';
OCCategories.changed = Contacts.UI.Card.categoriesChanged;
If OCCategories.changed is set that function will be called each time the categories have been changed
in the editor (add/delete/rescan) to allow the app to update the UI accordingly. The only argument to the function
is an array of the updated categories e.g.:
OCCategories.changed = function(categories) {
for(var category in categories) {
console.log(categories[category]);
}
}
To show the categories editor call:
OCCategories.edit()

353
core/js/tags.js Normal file
View File

@ -0,0 +1,353 @@
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.status === '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.status === '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.status === '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.status === '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);
});
}
}

View File

@ -23,19 +23,43 @@ $this->create('core_ajax_share', '/core/ajax/share.php')
// 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}/unfavorite/{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');

114
core/tags/controller.php Normal file
View File

@ -0,0 +1,114 @@
<?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();
}
}
}

View File

@ -1,19 +0,0 @@
<?php
$categories = isset($_['categories'])?$_['categories']:array();
?>
<div id="edit_categories_dialog" title="<?php p($l->t('Edit categories')); ?>">
<!-- ?php print_r($types); ? -->
<form method="post" id="categoryform">
<div class="scrollarea">
<ul id="categorylist">
<?php foreach($categories as $category): ?>
<li><input type="checkbox" name="categories[]" value="<?php p($category); ?>" /><?php p($category); ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="bottombuttons">
<input type="text" id="category_addinput" name="category" />
<button id="category_addbutton" disabled="disabled"><?php p($l->t('Add')); ?></button>
</div>
</form>
</div>

14
core/templates/tags.html Normal file
View File

@ -0,0 +1,14 @@
<div id="tagsdialog">
<div class="content">
<div class="scrollarea">
<ul class="taglist">
<li><input type="checkbox" name="ids[]" id="tag_{id}" value="{name}" />
<label for="tag_{id}">{name}</label>
</li>
</ul>
</div>
<div class="bottombuttons">
<input type="text" class="addinput" name="tag" placeholder="{addText}" />
</div>
</div>
</div>