Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwclouser@mozilla.com <wclouser@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2009-06-26 04:40:05 (GMT)
committer wclouser@mozilla.com <wclouser@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2009-06-26 04:40:05 (GMT)
commitab56f9f38526d5a9a05be9ebc07a18632907fcfa (patch)
treea80e7c520e0d72d3e83bc93da3843557bf17f6e2
parent07b2ade1f4d8827b5d6684c665ccfc473270f1ba (diff)
Merge /branches/webmocha/ -> /trunk/; r25690:28598. No testing done yet. To fix your
local copies: - run /bin/run_once/tags2categories.sql - run https://bugzilla.mozilla.org/attachment.cgi?id=385313 git-svn-id: http://svn.mozilla.org/addons/trunk@28602 4eb1ac78-321c-0410-a911-ec516a8615a5
-rwxr-xr-xbin/maintenance.php8
-rw-r--r--bin/run_once/tags2categories.sql17
-rw-r--r--bin/update-search-views.php12
-rw-r--r--site/app/app_controller.php2
-rw-r--r--site/app/config/bootstrap.php2
-rw-r--r--site/app/config/sql/remora.sql115
-rw-r--r--site/app/controllers/addons_controller.php166
-rw-r--r--site/app/controllers/admin_controller.php184
-rw-r--r--site/app/controllers/api_controller.php46
-rw-r--r--site/app/controllers/collections_controller.php2
-rw-r--r--site/app/controllers/components/amo.php38
-rw-r--r--site/app/controllers/components/audit.php24
-rw-r--r--site/app/controllers/components/developers.php82
-rw-r--r--site/app/controllers/components/pagination.php2
-rw-r--r--site/app/controllers/components/search.php23
-rw-r--r--site/app/controllers/developers_controller.php88
-rw-r--r--site/app/controllers/editors_controller.php68
-rw-r--r--site/app/controllers/facebook_controller.php24
-rw-r--r--site/app/controllers/localizers_controller.php51
-rw-r--r--site/app/controllers/search_controller.php22
-rw-r--r--site/app/controllers/sharing_api_controller.php44
-rw-r--r--site/app/controllers/tags_controller.php298
-rw-r--r--site/app/controllers/tests_controller.php2
-rw-r--r--site/app/locale/af/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ar/LC_MESSAGES/messages.po8
-rw-r--r--site/app/locale/ca/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/cs/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/cy/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/da/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/de/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/el/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/en_US/LC_MESSAGES/messages.po15
-rw-r--r--site/app/locale/es_ES/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/eu/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/fa/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/fi/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/fr/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/fy_NL/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ga_IE/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/he/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/hu/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/id/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/it/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ja/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ko/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/mn/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/nl/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/pl/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/pt_BR/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/pt_PT/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ro/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/ru/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/sk/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/sq/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/sv_SE/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/tr/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/uk/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/vi/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/zh_CN/LC_MESSAGES/messages.po6
-rw-r--r--site/app/locale/zh_TW/LC_MESSAGES/messages.po6
-rw-r--r--site/app/models/addon.php157
-rw-r--r--site/app/models/addon_category.php (renamed from site/app/models/addon_tag.php)26
-rw-r--r--site/app/models/addontype.php4
-rw-r--r--site/app/models/application.php4
-rw-r--r--site/app/models/category.php134
-rw-r--r--site/app/models/collection.php10
-rw-r--r--site/app/models/tag.php320
-rw-r--r--site/app/models/tag_stat.php21
-rw-r--r--site/app/models/tag_strength.php22
-rw-r--r--site/app/models/user_tag_addon.php20
-rw-r--r--site/app/tests/controllers/addons_controller.test.php17
-rw-r--r--site/app/tests/controllers/components/audit.test.php34
-rw-r--r--site/app/tests/controllers/components/developers.test.php58
-rw-r--r--site/app/tests/controllers/editors_controller.test.php46
-rw-r--r--site/app/tests/controllers/search_controller.test.php204
-rw-r--r--site/app/tests/controllers/tags_controller.test.php (copied from site/app/views/admin/tags_create.thtml)77
-rw-r--r--site/app/tests/controllers/users_controller.test.php4
-rw-r--r--site/app/tests/installation.test.php12
-rw-r--r--site/app/tests/models/addon.test.php205
-rw-r--r--site/app/tests/models/tag.test.php146
-rw-r--r--site/app/tests/models/translation_model.test.php4
-rw-r--r--site/app/tests/views/addons/display.test.php24
-rw-r--r--site/app/tests/views/developers/edit.test.php2
-rw-r--r--site/app/tests/views/helpers/addons_html.test.php2
-rw-r--r--site/app/views/addons/browse.thtml4
-rw-r--r--site/app/views/addons/browse_thumbs.thtml31
-rw-r--r--site/app/views/addons/category_landing.thtml10
-rw-r--r--site/app/views/addons/display.thtml26
-rw-r--r--site/app/views/addons/fortag.thtml9
-rw-r--r--site/app/views/addons/rss/categories.thtml6
-rw-r--r--site/app/views/addons/searchengines.thtml20
-rw-r--r--site/app/views/addons/themes_landing.thtml4
-rw-r--r--site/app/views/admin/categories.thtml (copied from site/app/views/admin/tags_create.thtml)35
-rw-r--r--site/app/views/admin/categories_create.thtml (copied from site/app/views/admin/tags_create.thtml)12
-rw-r--r--site/app/views/admin/categories_edit.thtml (renamed from site/app/views/admin/tags_edit.thtml)18
-rw-r--r--site/app/views/admin/lists.thtml4
-rw-r--r--site/app/views/admin/logs.thtml8
-rw-r--r--site/app/views/admin/tags.thtml49
-rw-r--r--site/app/views/api/collections_feed.thtml4
-rw-r--r--site/app/views/collections/ajax/addon_lookup.thtml1
-rw-r--r--site/app/views/developers/addon_edit.thtml2
-rw-r--r--site/app/views/developers/addon_edit_categories.thtml30
-rw-r--r--site/app/views/developers/addon_edit_tags.thtml (copied from site/app/views/admin/tags_create.thtml)49
-rw-r--r--site/app/views/editors/featured.thtml48
-rw-r--r--site/app/views/editors/review.thtml6
-rw-r--r--site/app/views/elements/addon_categories.thtml18
-rw-r--r--site/app/views/elements/addon_discussionheader.thtml2
-rw-r--r--site/app/views/elements/addon_listitem.thtml6
-rw-r--r--site/app/views/elements/addon_tags.thtml (copied from site/app/views/admin/tags_create.thtml)65
-rw-r--r--site/app/views/elements/amo2009/categories.thtml28
-rw-r--r--site/app/views/elements/amo2009/homepage_addon.thtml6
-rw-r--r--site/app/views/elements/amo2009/results_addon.thtml135
-rw-r--r--site/app/views/elements/amo2009/search.thtml8
-rw-r--r--site/app/views/elements/categories.thtml20
-rw-r--r--site/app/views/elements/collections_install_item.thtml2
-rw-r--r--site/app/views/elements/collections_interactive_addon.thtml2
-rw-r--r--site/app/views/elements/developers/adminmenu.thtml4
-rw-r--r--site/app/views/elements/developers/editbox.thtml2
-rw-r--r--site/app/views/elements/developers/localizermenu.thtml2
-rw-r--r--site/app/views/elements/feature.thtml6
-rw-r--r--site/app/views/elements/search.thtml8
-rw-r--r--site/app/views/elements/search_mini.thtml8
-rw-r--r--site/app/views/elements/sidebar.thtml2
-rw-r--r--site/app/views/facebook/browse.thtml8
-rw-r--r--site/app/views/helpers/addons_html.php2
-rw-r--r--site/app/views/localizers/tags.thtml18
-rw-r--r--site/app/views/pages/appversions.thtml2
-rw-r--r--site/app/views/search/index.thtml168
-rw-r--r--site/app/views/sharing_api/addon.thtml4
-rw-r--r--site/app/views/tags/ajax/tag_added.thtml (copied from site/app/views/admin/tags_create.thtml)39
-rw-r--r--site/app/views/tags/ajax/tag_lookup.thtml (copied from site/app/views/admin/tags_create.thtml)43
-rw-r--r--site/app/views/tags/tag_added.thtml (renamed from site/app/views/admin/tags_create.thtml)39
-rw-r--r--site/app/views/tags/top.thtml10
-rw-r--r--site/app/views/users/info.thtml4
-rw-r--r--site/app/webroot/css/amo2009/main-mozilla.css77
-rw-r--r--site/app/webroot/css/autocomplete.css49
-rw-r--r--site/app/webroot/css/developers.css73
-rw-r--r--site/app/webroot/js/editors.js2
-rwxr-xr-xsite/app/webroot/js/simile/ajax/simile-ajax-api.js2
-rw-r--r--site/app/webroot/js/tags.js80
140 files changed, 3244 insertions, 1182 deletions
diff --git a/bin/maintenance.php b/bin/maintenance.php
index 0e98475..5e5e696 100755
--- a/bin/maintenance.php
+++ b/bin/maintenance.php
@@ -471,7 +471,7 @@ switch ($action) {
tags AS t
INNER JOIN (
SELECT
- at.tag_id,
+ at.category_id,
COUNT(DISTINCT Addon.id) AS ct
FROM
addons AS Addon
@@ -479,7 +479,7 @@ switch ($action) {
ON (Addon.id = Version.addon_id)
INNER JOIN applications_versions AS av
ON (av.version_id = Version.id)
- INNER JOIN addons_tags AS at
+ INNER JOIN addons_categories AS at
ON (at.addon_id = Addon.id)
INNER JOIN files AS File
ON (Version.id = File.version_id
@@ -487,8 +487,8 @@ switch ($action) {
WHERE
Addon.status IN ({$valid_status})
AND Addon.inactive = 0
- GROUP BY at.tag_id
- ) AS j ON (t.id = j.tag_id)
+ GROUP BY at.category_id
+ ) AS j ON (t.id = j.category_id)
SET
t.count = j.ct
";
diff --git a/bin/run_once/tags2categories.sql b/bin/run_once/tags2categories.sql
new file mode 100644
index 0000000..67bc009
--- /dev/null
+++ b/bin/run_once/tags2categories.sql
@@ -0,0 +1,17 @@
+SET FOREIGN_KEY_CHECKS = 0;
+rename table tags to categories;
+rename table addons_tags to addons_categories;
+alter table addons_categories change tag_id category_id int(11) unsigned;
+rename table collections_tags to collections_categories;
+alter table collections_categories change tag_id category_id int(11) unsigned;
+SET FOREIGN_KEY_CHECKS = 1; -- new tables to support tagging feature
+--
+--
+-- Support for tag searching
+-- add new column 'tags' to text_search_summary
+alter table text_search_summary add column `tags` text NULL ;
+-- add new index which contains tags
+alter table text_search_summary add FULLTEXT KEY `na_su_de_ta` (`name`,`summary`,`description`,`tags`)
+-- add new index for searching on tags only
+alter table text_search_summary add FULLTEXT KEY `tags` (`tags`)
+
diff --git a/bin/update-search-views.php b/bin/update-search-views.php
index f1ef504..3caae09 100644
--- a/bin/update-search-views.php
+++ b/bin/update-search-views.php
@@ -83,13 +83,19 @@ $sql_commands[] = "INSERT INTO `text_search_summary`
a.weeklydownloads AS weeklydownloads,
`tr_name`.localized_string AS name,
`tr_summary`.localized_string AS summary,
- `tr_description`.localized_string AS description
+ `tr_description`.localized_string AS description,
+ tags
FROM addons AS a
LEFT JOIN translations AS `tr_name` ON (`tr_name`.id = a.`name`)
LEFT JOIN translations AS `tr_summary` ON (`tr_summary`.id = a.`summary` AND `tr_name`.locale = `tr_summary`.locale)
LEFT JOIN translations AS `tr_description`
- ON (`tr_description`.id = a.`description` AND `tr_name`.locale = `tr_description`.locale)
- WHERE `tr_name`.locale IS NOT NULL AND (
+ ON (`tr_description`.id = a.`description` AND `tr_name`.locale = `tr_description`.locale)
+ LEFT JOIN
+ ( select uta.addon_id, GROUP_CONCAT(distinct t.tag_text SEPARATOR '\n') as tags
+ from users_tags_addons uta, tags t
+ where uta.tag_id = t.id
+ group by uta.addon_id ) addon_tags ON ( a.id = addon_tags.addon_id)
+ WHERE `tr_name`.locale IS NOT NULL AND (
`tr_name`.localized_string IS NOT NULL
OR `tr_summary`.localized_string IS NOT NULL
OR `tr_description`.localized_string IS NOT NULL
diff --git a/site/app/app_controller.php b/site/app/app_controller.php
index 964e55b..5b8bfff 100644
--- a/site/app/app_controller.php
+++ b/site/app/app_controller.php
@@ -344,7 +344,7 @@ class AppController extends Controller
* circumventing the publish() function.
*/
function beforeRender() {
- $this->set('AmoTags', $this->Amo->getNavCategories());
+ $this->set('AmoCategories', $this->Amo->getNavCategories());
$this->set('AmoVersions', $this->Amo->getApplicationVersions());
$this->set('AmoPlatforms', $this->Platform->getNames());
$this->set('AmoAddonTypes', $this->Addontype->getNames());
diff --git a/site/app/config/bootstrap.php b/site/app/config/bootstrap.php
index 2b3525c..fa055f5 100644
--- a/site/app/config/bootstrap.php
+++ b/site/app/config/bootstrap.php
@@ -122,7 +122,7 @@ $lang = $language_config->detectCurrentLanguage();
// This comment is now longer than the code change.
if (array_key_exists('url',$_GET) &&
!preg_match('/\/api\//', $_GET['url']) &&
- preg_match('/[^\w\d\/\.\-_!: ]/u',$_GET['url'])) {
+ preg_match('/[^\w\d\/\.\-_!": ]/u',$_GET['url'])) {
header("HTTP/1.1 400 Bad Request");
exit;
}
diff --git a/site/app/config/sql/remora.sql b/site/app/config/sql/remora.sql
index c5dd75d..33646b2 100644
--- a/site/app/config/sql/remora.sql
+++ b/site/app/config/sql/remora.sql
@@ -91,19 +91,19 @@ CREATE TABLE `addons` (
--
--- Table structure for table `addons_tags`
+-- Table structure for table `addons_categories`
--
-DROP TABLE IF EXISTS `addons_tags`;
-CREATE TABLE `addons_tags` (
+DROP TABLE IF EXISTS `addons_categories`;
+CREATE TABLE `addons_categories` (
`addon_id` int(11) unsigned NOT NULL default '0',
- `tag_id` int(11) unsigned NOT NULL default '0',
+ `category_id` int(11) unsigned NOT NULL default '0',
`feature` int(1) unsigned NOT NULL default '0',
`feature_locales` varchar(255) default NULL,
- PRIMARY KEY (`addon_id`,`tag_id`),
- KEY `tag_id` (`tag_id`),
- CONSTRAINT `addons_tags_ibfk_3` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
- CONSTRAINT `addons_tags_ibfk_4` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
+ PRIMARY KEY (`addon_id`,`category_id`),
+ KEY `category_id` (`category_id`),
+ CONSTRAINT `addons_categories_ibfk_3` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `addons_categories_ibfk_4` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -812,11 +812,11 @@ CREATE TABLE `stats_share_counts` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
--- Table structure for table `tags`
+-- Table structure for table `categories`
--
-DROP TABLE IF EXISTS `tags`;
-CREATE TABLE `tags` (
+DROP TABLE IF EXISTS `categories`;
+CREATE TABLE `categories` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` int(11) unsigned default NULL,
`description` int(11) unsigned default NULL,
@@ -829,12 +829,12 @@ CREATE TABLE `tags` (
PRIMARY KEY (`id`),
KEY `addontype_id` (`addontype_id`),
KEY `application_id` (`application_id`),
- KEY `tags_ibfk_3` (`name`),
- KEY `tags_ibfk_4` (`description`),
- CONSTRAINT `tags_ibfk_1` FOREIGN KEY (`addontype_id`) REFERENCES `addontypes` (`id`),
- CONSTRAINT `tags_ibfk_2` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`),
- CONSTRAINT `tags_ibfk_3` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
- CONSTRAINT `tags_ibfk_4` FOREIGN KEY (`description`) REFERENCES `translations` (`id`)
+ KEY `categories_ibfk_3` (`name`),
+ KEY `categories_ibfk_4` (`description`),
+ CONSTRAINT `categories_ibfk_1` FOREIGN KEY (`addontype_id`) REFERENCES `addontypes` (`id`),
+ CONSTRAINT `categories_ibfk_2` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`),
+ CONSTRAINT `categories_ibfk_3` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `categories_ibfk_4` FOREIGN KEY (`description`) REFERENCES `translations` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -1106,15 +1106,15 @@ CREATE TABLE `collection_promos` (
CONSTRAINT `collection_features_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-DROP TABLE IF EXISTS `collections_tags`;
-CREATE TABLE `collections_tags` (
+DROP TABLE IF EXISTS `collections_categories`;
+CREATE TABLE `collections_categories` (
`collection_id` int(11) unsigned NOT NULL ,
- `tag_id` int(11) unsigned NOT NULL ,
- PRIMARY KEY ( `collection_id` , `tag_id` ),
+ `category_id` int(11) unsigned NOT NULL ,
+ PRIMARY KEY ( `collection_id` , `category_id` ),
KEY `collection_id` (`collection_id`),
- KEY `tag_id` (`tag_id`),
- CONSTRAINT `collections_tags_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `addons` (`id`),
- CONSTRAINT `collections_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
+ KEY `category_id` (`category_id`),
+ CONSTRAINT `collections_categories_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `collections_categories_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
DROP TABLE IF EXISTS `collection_subscriptions`;
@@ -1186,6 +1186,49 @@ CREATE TABLE `schema_version` (
`version` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS `tags`;
+CREATE TABLE `tags` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `tag_text` varchar(128) NOT NULL,
+ `blacklisted` tinyint(1) NOT NULL default 0,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `tag_text` (`tag_text`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `tag_stat`;
+CREATE TABLE `tag_stat` (
+ `tag_id` int(11) unsigned NOT NULL,
+ `num_addons` int(11) unsigned NOT NULL default '0',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`tag_id`),
+ CONSTRAINT `tag_stat_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `tag_strength`;
+CREATE TABLE `tag_strength` (
+ `tag1_id` int(11) unsigned NOT NULL,
+ `tag2_id` int(11) unsigned NOT NULL,
+ `strength` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`tag1_id`, `tag2_id`),
+ CONSTRAINT `tag_strength_ibfk_1` FOREIGN KEY (`tag1_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `tag_strength_ibfk_2` FOREIGN KEY (`tag2_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `users_tags_addons`;
+CREATE TABLE `users_tags_addons` (
+ `user_id` int(11) unsigned NOT NULL,
+ `tag_id` int(11) unsigned NOT NULL,
+ `addon_id` int(11) unsigned NOT NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`user_id`,`tag_id`,`addon_id`),
+ INDEX (`tag_id`),
+ INDEX (`addon_id`),
+ CONSTRAINT `users_tags_addons_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `users_tags_addons_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `users_tags_addons_ibfk_3` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
--
-- Default data that doesn't change over time (or isn't supposed to anyway).
--
@@ -1238,6 +1281,7 @@ DROP TABLE IF EXISTS `userevents`;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
/* These are my TRIGGERS. */
CREATE TRIGGER collections_update_addon_count_insert
@@ -1267,3 +1311,26 @@ CREATE TRIGGER collections_update_subscriber_count_delete
UPDATE collections AS c
SET c.subscribers = c.subscribers - 1
WHERE c.id=OLD.collection_id;
+
+DELIMITER |
+
+drop trigger if exists trg_tag_stat_inc |
+
+CREATE TRIGGER trg_tag_stat_inc AFTER INSERT ON `users_tags_addons`
+ FOR EACH ROW
+ BEGIN
+ insert ignore INTO tag_stat(tag_id, num_addons, modified) values(NEW.tag_id, 0, now());
+ UPDATE `tag_stat` set num_addons = (num_addons+1) WHERE tag_id = NEW.tag_id;
+ END;
+|
+
+drop trigger if exists trg_tag_stat_dec |
+
+CREATE TRIGGER trg_tag_stat_dec AFTER DELETE ON `users_tags_addons`
+ FOR EACH ROW
+ BEGIN
+ UPDATE `tag_stat` set num_addons = (num_addons-1) WHERE tag_id = OLD.tag_id;
+ END;
+
+|
+DELIMITER ;
diff --git a/site/app/controllers/addons_controller.php b/site/app/controllers/addons_controller.php
index 75d19a6..963ffb8 100644
--- a/site/app/controllers/addons_controller.php
+++ b/site/app/controllers/addons_controller.php
@@ -46,10 +46,9 @@
class AddonsController extends AppController
{
var $name = 'Addons';
+
var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
- var $uses = array('Addon', 'AddonCollection', 'AddonTag', 'Addontype', 'Application', 'CollectionFeatures',
- 'Feature', 'File', 'GlobalStat', 'License', 'Platform', 'Preview', 'Tag', 'Translation',
- 'Review', 'Version', 'Collection', 'CollectionPromo');
+ var $uses = array('Addon', 'AddonCollection', 'AddonCategory', 'Addontype', 'Application', 'CollectionFeatures', 'Feature', 'File', 'GlobalStat', 'License', 'Platform', 'Preview', 'Category', 'Translation', 'Review', 'Version', 'Collection', 'CollectionPromo','Tag');
var $components = array('Amo', 'Image', 'Pagination', 'Session', 'Userfunc');
var $helpers = array('Html', 'Link', 'Time', 'Localization', 'Ajax', 'Number', 'Pagination');
var $namedArgs = true;
@@ -164,8 +163,8 @@ class AddonsController extends AppController
*/
function display($id = null) {
global $valid_status;
- $this->publish('jsAdd', array('jquery-ui/ui.lightbox'));
- $this->publish('cssAdd', array('jquery-lightbox'));
+ $this->publish('jsAdd', array('jquery-ui/ui.lightbox','jquery.autocomplete.pack.js','tags.js'));
+ $this->publish('cssAdd', array('jquery-lightbox','autocomplete'));
$this->layout = 'amo2009';
$this->set('bodyclass', 'inverse');
@@ -177,6 +176,7 @@ class AddonsController extends AppController
$loggedIn = $this->Session->check('User')? true : false;
$this->set('loggedIn', $loggedIn);
+ if ($loggedIn) { $user=$this->Session->read('User'); }
if (!$id || !is_numeric($id)) {
$this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
@@ -275,24 +275,34 @@ class AddonsController extends AppController
}
$this->publish('previews', $this->Preview->findAllByAddonId($id, array('id', 'addon_id', 'caption'), 'highlight desc'));
-
$this->publish('addon', $addon_data);
$this->publish('addonIconPath', $this->Image->getAddonIconURL($id), false);
$this->publish('addonPreviewPath', $this->Image->getHighlightedPreviewURL($id));
$this->pageTitle = sprintf(_('addons_display_pagetitle'), $addon_data['Translation']['name']['string']). ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
- // get the tags that are related to the addon, so that they have translation data
- $_related_tag_ids = array();
- foreach ($addon_data['Tag'] as $tagvalue){
- $_related_tag_ids[] = $tagvalue['id'];
+ // get the categories that are related to the addon, so that they have translation data
+ $_related_category_ids = array();
+ foreach ($addon_data['Category'] as $categoryvalue){
+ $_related_category_ids[] = $categoryvalue['id'];
}
- if (!empty($_related_tag_ids))
- $related_tags = $this->Tag->findAll("Tag.id IN (".implode(',', $_related_tag_ids).") AND (Tag.application_id = ".APP_ID." OR Tag.application_id IS NULL)");
+ if (!empty($_related_category_ids))
+ $related_categories = $this->Category->findAll("Category.id IN (".implode(',', $_related_category_ids).") AND (Category.application_id = ".APP_ID." OR Category.application_id IS NULL)");
else
- $related_tags = array();
+ $related_categories = array();
+
+ $this->publish('relatedCategories', $related_categories);
- $this->publish('relatedTags', $related_tags);
+
+
+ // Make the tag list, passing in this addon and the currently logged in user
+ if (!$loggedIn) { $user = null; }
+ $tags = $this->Tag->makeTagList($addon_data, $user);
+ $this->publish('tags', $tags);
+ $this->publish('userTags', $tags['userTags']);
+ $this->publish('developerTags', $tags['developerTags']);
+ $this->publish('addon_id', $addon_data['Addon']['id']);
+
// The platforms section is necessary because of CakePHP bug #1183 (https://trac.cakephp.org/ticket/1183). We
// need the translated strings in the model to offer the right platform to users.
@@ -420,7 +430,7 @@ class AddonsController extends AppController
global $app_listedtypes;
$associations = array(
- 'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
+ 'single_category', 'all_categories', 'authors', 'compatible_apps', 'files',
'latest_version', 'list_details'
);
$list_num = 5;
@@ -473,7 +483,7 @@ class AddonsController extends AppController
$teaser_collections = array();
$associations = array(
- 'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
+ 'single_category', 'all_categories', 'authors', 'compatible_apps', 'files',
'latest_version', 'list_details'
);
@@ -590,8 +600,8 @@ class AddonsController extends AppController
$category = isset($this->namedArgs['cat']) ?
$this->namedArgs['cat'] : 'all';
- $this->Tag->unbindFully();
- $this_tag = $this->Tag->findById($category);
+ $this->Category->unbindFully();
+ $this_category = $this->Category->findById($category);
// show experimental add-ons?
if (isset($this->params['url']['exp'])) {
@@ -613,7 +623,7 @@ class AddonsController extends AppController
$displaystatuses = ($show_exp ? $valid_status : array(STATUS_PUBLIC));
// fetch a list of all subcategories
- $subcats = $this->Amo->getTags(APP_ID, $addontype);
+ $subcats = $this->Amo->getCategories(APP_ID, $addontype);
// fetch counts for all categories
$subcat_totals = $this->Addon->countAddonsInAllCategories(
@@ -664,7 +674,7 @@ class AddonsController extends AppController
);
$this->set('type', $addontype);
- $this->set('this_tag', $this_tag);
+ $this->set('this_category', $this_category);
$this->publish('addons', $addons);
$this->publish('show_limit', $_limit);
@@ -681,7 +691,7 @@ class AddonsController extends AppController
switch($addontype) {
case ADDON_THEME:
- $this->pageTitle = sprintf(___('addons_browse_categories_header_theme'), $this_tag['Translation']['name']['string'], APP_PRETTYNAME);
+ $this->pageTitle = sprintf(___('addons_browse_categories_header_theme'), $this_category['Translation']['name']['string'], APP_PRETTYNAME);
break;
default:
$this->pageTitle = sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
@@ -834,12 +844,12 @@ class AddonsController extends AppController
$this->Amo->clean($category);
$this->publish('cat_id', $category);
- $this->Tag->unbindFully();
- $this_tag = $this->Tag->findById($category);
- $this->publish('this_tag', $this_tag);
+ $this->Category->unbindFully();
+ $this_category = $this->Category->findById($category);
+ $this->publish('this_category', $this_category);
// Build a minimal set of addon details for publishing to view.
- $_feat_ids = $this->AddonTag->getRandomAddons($category, true, 6);
+ $_feat_ids = $this->AddonCategory->getRandomAddons($category, true, 6);
if (count($_feat_ids) > 0) {
$_order_by = 'FIELD(Addon.id, '.implode(',', $_feat_ids).')';
} else {
@@ -894,7 +904,7 @@ class AddonsController extends AppController
$this->publish('bigHeaderText',
sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
- $this->pageTitle = $this_tag['Translation']['name']['string']. " :: " .
+ $this->pageTitle = $this_category['Translation']['name']['string']. " :: " .
sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
$this->publish('rssAdd', array(
"/browse/type:{$addontype}/cat:{$category}/format:rss?sort=updated"
@@ -918,11 +928,11 @@ class AddonsController extends AppController
// type:1 && cat:all shows a global add-ons list (not extensions only)
if ($addontype == ADDON_EXTENSION && $category == 'all') {
- $this_tag = array();
+ $this_category = array();
$addontype = $app_listedtypes[APP_ID];
} else {
- $this->Tag->unbindFully();
- $this_tag = $this->Tag->findById($category);
+ $this->Category->unbindFully();
+ $this_category = $this->Category->findById($category);
}
// determine list sort order
@@ -990,7 +1000,7 @@ class AddonsController extends AppController
// get enough addons for one page.
$addons = $this->Addon->getAddonsByCategory(null, $displaystatuses,
$addontype, $category, $sort_by, $sort_dir, $_limit, $_page, '', true);
- if ($category!='all' && empty($this_tag) || empty($addons)) {
+ if ($category!='all' && empty($this_category) || empty($addons)) {
$this->flash(_('error_browse_no_addons'), '/browse/type:' . $addontype, 3);
return;
}
@@ -1004,27 +1014,27 @@ class AddonsController extends AppController
}
// get other categories list (or all, if this is a complete list)
- $_tags = $this->Tag->query("SELECT DISTINCT t.id FROM tags AS t "
- ."INNER JOIN addons_tags AS at ON (t.id = at.tag_id) "
+ $_categories = $this->Category->query("SELECT DISTINCT t.id FROM categories AS t "
+ ."INNER JOIN addons_categories AS at ON (t.id = at.category_id) "
."WHERE ".($category == 'all'?'1':"t.id <> '{$category}'")." "
."AND t.addontype_id = '{$addontype}' AND t.application_id = " . APP_ID . ";"
);
- $tag_list = array();
- if (!empty($_tags)) {
- $_tag_ids = array();
- foreach($_tags as $_tag) $_tag_ids[] = $_tag['t']['id'];
- $this->Tag->unbindFully();
- $tag_list = $this->Tag->findAllById($_tag_ids);
- // sort tags by name
- $_tag_names = array();
- foreach($tag_list as $_tag) $_tag_names[] = $_tag['Translation']['name']['string'];
- array_multisort($_tag_names, SORT_ASC, $tag_list);
+ $category_list = array();
+ if (!empty($_categories)) {
+ $_category_ids = array();
+ foreach($_categories as $_category) $_category_ids[] = $_category['t']['id'];
+ $this->Category->unbindFully();
+ $category_list = $this->Category->findAllById($_category_ids);
+ // sort categories by name
+ $_category_names = array();
+ foreach($category_list as $_category) $_category_names[] = $_category['Translation']['name']['string'];
+ array_multisort($_category_names, SORT_ASC, $category_list);
}
// set data available to view
- $this->publish('this_tag', $this_tag);
+ $this->publish('this_category', $this_category);
$this->set('type', $addontype);
- $this->publish('tagList', $tag_list);
+ $this->publish('categoryList', $category_list);
// set layout details and render view
if ($category == 'all') {
@@ -1037,7 +1047,7 @@ class AddonsController extends AppController
default: $_title = ''; break;
}
} else {
- $_title = sprintf(_('addons_browse_browse_category'), $this_tag['Translation']['name']['string']);
+ $_title = sprintf(_('addons_browse_browse_category'), $this_category['Translation']['name']['string']);
}
if ($format != 'rss') {
$this->pageTitle = $_title . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
@@ -1075,26 +1085,27 @@ class AddonsController extends AppController
// fetch the category belonging to this hybrid page
$category = array_search(ADDON_SEARCH, $hybrid_categories[APP_ID]);
if ($category) {
- $this->Tag->unbindfully();
- $this_tag = $this->Tag->findById($category);
+ $this->Category->unbindfully();
+ $this_category = $this->Category->findById($category);
} else {
- $this_tag = null;
+ $this_category = null;
}
- $this->publish('this_tag', $this_tag);
+ $this->publish('this_category', $this_category);
// fetch a list of all subcategories
- $subcats = $this->Amo->getTags(APP_ID, ADDON_SEARCH);
+ $subcats = $this->Amo->getCategories(APP_ID, ADDON_SEARCH);
$this->publish('subcats', $subcats);
// make subcategory ID list to grab recommendations from
$subcat_ids = array();
foreach ($subcats as $subcat)
- $subcat_ids[] = $subcat['Tag']['id'];
+ $subcat_ids[] = $subcat['Category']['id'];
// add hybrid category for possible other recommendations
- $subcat_ids[] = $this_tag['Tag']['id'];
+ $subcat_ids[] = $this_category['Category']['id'];
// fetch up to 4 recommended add-ons
- $_feat_ids = $this->AddonTag->getRandomAddons($subcat_ids, true, 4);
+ $_feat_ids = $this->AddonCategory->getRandomAddons($subcat_ids, true, 4);
+
if (!empty($_feat_ids)) {
$associations = array(
'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
@@ -1278,16 +1289,16 @@ class AddonsController extends AppController
$format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
// fetch a list of all subcategories
- $subcats = $this->Amo->getTags(APP_ID, ADDON_THEME);
+ $subcats = $this->Amo->getCategories(APP_ID, ADDON_THEME);
$this->publish('subcats', $subcats);
// make subcategory ID list to grab recommendations from
$subcat_ids = array();
foreach ($subcats as $subcat)
- $subcat_ids[] = $subcat['Tag']['id'];
+ $subcat_ids[] = $subcat['Category']['id'];
+
+ $_feat_ids = $this->AddonCategory->getRandomAddons($subcat_ids, true, 4);
- // fetch up to 2 recommended add-ons
- $_feat_ids = $this->AddonTag->getRandomAddons($subcat_ids, true, 4);
if (!empty($_feat_ids)) {
$associations = array(
'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
@@ -1343,11 +1354,11 @@ class AddonsController extends AppController
{
$category = $this->namedArgs['cat'];
$this->Amo->clean($category);
- $criteria = "feature > 0 AND tag_id='".$category."'";
- $featAddons = $this->AddonTag->findAll($criteria);
+ $criteria = "feature > 0 AND category_id='".$category."'";
+ $featAddons = $this->AddonCategory->findAll($criteria);
foreach ($featAddons as $_addon)
- $_addon_ids[] = $_addon['AddonTag']['addon_id'];
+ $_addon_ids[] = $_addon['AddonCategory']['addon_id'];
} else {
$featAddons = $this->Feature->findAll($criteria);
@@ -1404,11 +1415,11 @@ class AddonsController extends AppController
$this->Addon->bindModel(
array(
'hasAndBelongsToMany' => array(
- 'Tag' => array(
- 'className' => 'Tag',
- 'joinTable' => 'addons_tags',
+ 'Category' => array(
+ 'className' => 'Category',
+ 'joinTable' => 'addons_categories',
'foreignKey' => 'addon_id',
- 'associationForeignKey'=> 'tag_id'
+ 'associationForeignKey'=> 'category_id'
),
'User' => array(
'className' => 'User',
@@ -1447,16 +1458,16 @@ class AddonsController extends AppController
else {
$this->publish('policy', 1);
}
- // get the tags that are related to the addon, so that they have translation data
- $_related_tag_ids = array();
- foreach ($this_addon['Tag'] as $tagvalue) {
- $_related_tag_ids[] = $tagvalue['id'];
+ // get the categories that are related to the addon, so that they have translation data
+ $_related_category_ids = array();
+ foreach ($this_addon['Category'] as $categoryvalue) {
+ $_related_category_ids[] = $categoryvalue['id'];
}
- $related_tags = $this->Tag->findAll(array('Tag.id' => $_related_tag_ids, 'Tag.application_id' => APP_ID));
- unset($_related_tag_ids);
+ $related_categories = $this->Category->findAll(array('Category.id' => $_related_category_ids, 'Category.application_id' => APP_ID));
+ unset($_related_category_ids);
- $this->publish('relatedTags', $related_tags);
+ $this->publish('relatedCategories', $related_categories);
$this->publish('addon', $this_addon);
$this->pageTitle = sprintf(_('addons_display_pagetitle'), $this_addon['Translation']['name']['string']). ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
@@ -1588,6 +1599,19 @@ class AddonsController extends AppController
return;
}
}
+
+ /**
+ * Gets all the addons for this tag
+ */
+ function fortag($tag_id) {
+ $tag = $this->Tag->findById($tag_id);
+ $this->publish("tag_id", $tag['Tag']['id']);
+ $this->publish("tag_text", $tag['Tag']['tag_text']);
+
+ $addons = $this->Addon->getAddonsByTag($tag_id);
+ $this->publish("addons", $addons);
+ }
+
}
diff --git a/site/app/controllers/admin_controller.php b/site/app/controllers/admin_controller.php
index c3c7472..f67d5fb 100644
--- a/site/app/controllers/admin_controller.php
+++ b/site/app/controllers/admin_controller.php
@@ -40,13 +40,15 @@
class AdminController extends AppController
{
var $name = 'Admin';
- var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Cannedresponse', 'Collection', 'CollectionFeatures', 'CollectionPromo', 'Eventlog', 'Feature', 'File', 'Group', 'Platform', 'Tag', 'Translation', 'User', 'Version', 'Memcaching');
- var $components = array('Amo', 'Audit', 'Developers', 'Error', 'Versioncompare');
- var $helpers = array('Html', 'Javascript');
+
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Category', 'Cannedresponse', 'Collection', 'CollectionFeatures', 'CollectionPromo', 'Eventlog', 'Feature', 'File', 'Group', 'Platform', 'Tag', 'Translation', 'User', 'Version', 'Memcaching');
+ var $components = array('Amo', 'Audit', 'Developers', 'Error', 'Versioncompare', 'Pagination');
+ var $helpers = array('Html', 'Javascript', 'Pagination');
+
//These defer to their own access checks
var $aclExceptions = array('index', 'summary',
'addonLookup', 'userLookup',
- 'addontypes', 'tags', 'platforms', 'responses');
+ 'addontypes', 'categories', 'platforms', 'responses');
/**
* Require login for all actions
@@ -767,13 +769,13 @@ class AdminController extends AppController
/**
* Category Manager
*/
- function tags($action = '', $id = 0) {
+ function categories($action = '', $id = 0) {
//Part of the Lists permission
if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
$this->Amo->accessDenied();
}
- $this->breadcrumbs['Category Manager'] = '/admin/tags';
+ $this->breadcrumbs['Category Manager'] = '/admin/categories';
$this->set('breadcrumbs', $this->breadcrumbs);
$applications = array('All');
@@ -792,84 +794,84 @@ class AdminController extends AppController
$this->Amo->clean($id);
if ($action == 'edit') {
- $this->_tagEdit($id);
+ $this->_categoryEdit($id);
return;
}
elseif ($action == 'create') {
- $this->_tagCreate($id);
+ $this->_categoryCreate($id);
return;
}
}
- $tags = $this->Tag->findAll();
+ $categories = $this->Category->findAll();
- foreach ($tags as $k => $tag) {
- $tags[$k]['application'] = !empty($applications[$tag['Tag']['application_id']]) ? $applications[$tag['Tag']['application_id']] : 'All';
- $tags[$k]['addontype'] = $addontypes[$tag['Tag']['addontype_id']];
+ foreach ($categories as $k => $category) {
+ $categories[$k]['application'] = !empty($applications[$category['Category']['application_id']]) ? $applications[$category['Category']['application_id']] : 'All';
+ $categories[$k]['addontype'] = $addontypes[$category['Category']['addontype_id']];
- $count = $this->Tag->query("SELECT COUNT(*) FROM addons_tags WHERE tag_id='{$tag['Tag']['id']}'");
- $tags[$k]['count'] = $count[0][0]['COUNT(*)'];
+ $count = $this->Category->query("SELECT COUNT(*) FROM addons_categories WHERE category_id='{$category['Category']['id']}'");
+ $categories[$k]['count'] = $count[0][0]['COUNT(*)'];
}
- $this->set('tags', $tags);
+ $this->set('categories', $categories);
$this->set('page', 'lists');
- $this->set('subpage', 'tags');
- $this->render('tags');
+ $this->set('subpage', 'categories');
+ $this->render('categories');
}
/**
- * Edit Tags
+ * Edit Categories
*/
- function _tagEdit($id) {
- $this->breadcrumbs['Edit Category'] = '/admin/tags/edit/'.$id;
+ function _categoryEdit($id) {
+ $this->breadcrumbs['Edit Category'] = '/admin/categories/edit/'.$id;
$this->set('breadcrumbs', $this->breadcrumbs);
- $this->Tag->id = $id;
+ $this->Category->id = $id;
if (!empty($this->data)) {
//Delete
if (!empty($_POST['delete'])) {
- //Retrieve tag to store name in log
- $tag = $this->Tag->read();
+ //Retrieve category to store name in log
+ $category = $this->Category->read();
- $this->Group->execute("DELETE FROM addons_tags WHERE tag_id='{$id}'");
- $this->Group->execute("DELETE FROM tags WHERE id='{$id}'");
+ $this->Group->execute("DELETE FROM addons_categories WHERE category_id='{$id}'");
+ $this->Group->execute("DELETE FROM categories WHERE id='{$id}'");
//Log admin action
- $this->Eventlog->log($this, 'admin', 'tag_delete', null, $id, null, $tag['Translation']['name']['string']);
+ $this->Eventlog->log($this, 'admin', 'category_delete', null, $id, null, $category['Translation']['name']['string']);
- $this->flash('Category deleted successfully.', '/admin/tags');
+ $this->flash('Category deleted successfully.', '/admin/categories');
return;
}
//Edit
else {
// Must manually set application id to null if "All" is selected
- if (empty($this->data['Tag']['application_id']))
- $this->data['Tag']['application_id'] = NULL;
+ if (empty($this->data['Category']['application_id']))
+ $this->data['Category']['application_id'] = NULL;
- $this->Tag->save($this->data['Tag']);
- $this->Tag->execute("UPDATE tags SET weight='".$this->data['Tag']['weight']."' WHERE id='{$id}'");
+ $this->Category->save($this->data['Category']);
+ $this->Category->execute("UPDATE categories SET weight='".$this->data['Category']['weight']."' WHERE id='{$id}'");
//Log admin action
- $this->Eventlog->log($this, 'admin', 'tag_edit', null, $id);
+ $this->Eventlog->log($this, 'admin', 'category_edit', null, $id);
//Save translated fields (name, description)
- $this->Developers->saveTranslations($this->data, array('Tag'));
+ $this->Developers->saveTranslations($this->data, array('Category'));
- $this->flash('Category updated!', '/admin/tags');
+ $this->flash('Category updated!', '/admin/categories');
return;
}
}
- $tag = $this->Tag->read();
+ $category = $this->Category->read();
- $this->set('tag', $tag);
+ $this->set('category', $category);
$localizedFields = array(
'name' => array(
'type' => 'input',
'display' => 'Category Name',
- 'model' => 'Tag',
+ 'model' => 'Category',
'field' => 'name',
'attributes' => array(
'size' => 40
@@ -878,7 +880,7 @@ class AdminController extends AppController
'description' => array(
'type' => 'textarea',
'display' => 'Category Description',
- 'model' => 'Tag',
+ 'model' => 'Category',
'field' => 'description',
'attributes' => array(
'cols' => 60,
@@ -892,10 +894,10 @@ class AdminController extends AppController
foreach (array_keys($valid_languages) as $key) {
$languages[$key] = $native_languages[$key]['native'];
- $this->Tag->setLang($key, $this);
- $tagL = $this->Tag->read();
+ $this->Category->setLang($key, $this);
+ $categoryL = $this->Category->read();
- foreach ($tagL['Translation'] as $field => $translation) {
+ foreach ($categoryL['Translation'] as $field => $translation) {
if ($translation['locale'] == $key) {
$info[$key][$field] = $translation['string'];
}
@@ -912,31 +914,31 @@ class AdminController extends AppController
'localizedFields' => $localizedFields));
$this->set('page', 'lists');
- $this->set('subpage', 'tags');
- $this->render('tags_edit');
+ $this->set('subpage', 'categories');
+ $this->render('categories_edit');
}
/**
- * Create Tags
+ * Create Categories
*/
- function _tagCreate() {
- $this->breadcrumbs['Create Category'] = '/admin/tags/create';
+ function _categoryCreate() {
+ $this->breadcrumbs['Create Category'] = '/admin/categories/create';
$this->set('breadcrumbs', $this->breadcrumbs);
if (!empty($this->data)) {
// Must manually set application id to null if "All" is selected
- if (empty($this->data['Tag']['application_id']))
- $this->data['Tag']['application_id'] = NULL;
+ if (empty($this->data['Category']['application_id']))
+ $this->data['Category']['application_id'] = NULL;
- $this->Tag->save($this->data['Tag']);
+ $this->Category->save($this->data['Category']);
//Log admin action
- $this->Eventlog->log($this, 'admin', 'tag_create', null, $this->Tag->getLastInsertID());
+ $this->Eventlog->log($this, 'admin', 'category_create', null, $this->Category->getLastInsertID());
//Save translated fields (name, description)
- $this->Developers->saveTranslations($this->data, array('Tag'));
+ $this->Developers->saveTranslations($this->data, array('Category'));
- $this->flash('Category created!', '/admin/tags');
+ $this->flash('Category created!', '/admin/categories');
return;
}
@@ -944,7 +946,7 @@ class AdminController extends AppController
'name' => array(
'type' => 'input',
'display' => 'Category Name',
- 'model' => 'Tag',
+ 'model' => 'Category',
'field' => 'name',
'attributes' => array(
'size' => 40
@@ -953,7 +955,7 @@ class AdminController extends AppController
'description' => array(
'type' => 'textarea',
'display' => 'Category Description',
- 'model' => 'Tag',
+ 'model' => 'Category',
'field' => 'description',
'attributes' => array(
'cols' => 60,
@@ -967,9 +969,9 @@ class AdminController extends AppController
foreach (array_keys($valid_languages) as $key) {
$languages[$key] = $native_languages[$key]['native'];
- $this->Tag->setLang($key, $this);
+ $this->Category->setLang($key, $this);
- foreach ($this->Tag->translated_fields as $field) {
+ foreach ($this->Category->translated_fields as $field) {
$info[$key][$field] = '';
}
}
@@ -981,10 +983,68 @@ class AdminController extends AppController
'localizedFields' => $localizedFields));
$this->set('page', 'lists');
+ $this->set('subpage', 'categories');
+ $this->render('categories_create');
+ }
+
+ /**
+ * Tags Manager
+ */
+ function tags($action = '', $id = 0) {
+ //Part of the Lists permission
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->breadcrumbs['Tag Manager'] = '/admin/tags';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+
+ if ($action == 'delete') {
+ $this->_tagDelete($id);
+ return;
+ }
+ elseif ($action == 'blacklist') {
+ $this->_tagBlacklist($id);
+ return;
+ }
+ elseif ($action == 'unblacklist') {
+ $this->_tagUnBlacklist($id);
+ return;
+ }
+ }
+
+ // $tags = $this->Tag->findAll();
+ $criteria=NULL;
+ $this->Pagination->modelClass='Tag';
+
+ list($order,$limit,$page) = $this->Pagination->init($criteria, array('modelClass'=>'Tag')); // Added
+ // $order=str_replace('Addon','Tag', $order);
+ $tags = $this->Tag->findAll($criteria, NULL, $order, $limit, $page); // Extra parameters added
+
+ $this->set('tags', $tags);
+ $this->set('page', 'lists');
$this->set('subpage', 'tags');
- $this->render('tags_create');
+ $this->render('tags');
}
-
+
+ function _tagBlacklist($tag_id) {
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+ $this->Tag->blacklistTag($tag_id);
+ $this->redirect('/admin/tags');
+ }
+
+ function _tagUnBlacklist($tag_id) {
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+ $this->Tag->unblacklistTag($tag_id);
+ $this->redirect('/admin/tags');
+ }
/**
* Platform Manager
@@ -1121,7 +1181,7 @@ class AdminController extends AppController
$this->Developers->saveTranslations($this->data, array('Platform'));
//Log admin action
- $this->Eventlog->log($this, 'admin', 'platform_create', null, $this->Tag->getLastInsertID());
+ $this->Eventlog->log($this, 'admin', 'platform_create', null, $this->Category->getLastInsertID());
$this->flash('Platform created!', '/admin/platforms');
return;
@@ -1153,9 +1213,9 @@ class AdminController extends AppController
foreach (array_keys($valid_languages) as $key) {
$languages[$key] = $native_languages[$key]['native'];
- $this->Tag->setLang($key, $this);
+ $this->Category->setLang($key, $this);
- foreach ($this->Tag->translated_fields as $field) {
+ foreach ($this->Category->translated_fields as $field) {
$info[$key][$field] = '';
}
}
@@ -1537,7 +1597,7 @@ class AdminController extends AppController
}
/**
- * Create Tags
+ * Create Categories
*/
function _responseCreate() {
$this->breadcrumbs['Create Response'] = '/admin/responses/create';
diff --git a/site/app/controllers/api_controller.php b/site/app/controllers/api_controller.php
index 3eee8a9..3231e2b 100644
--- a/site/app/controllers/api_controller.php
+++ b/site/app/controllers/api_controller.php
@@ -54,7 +54,7 @@ class ApiController extends AppController
// some of this is excessive but will likely be needed as
// development continues
var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
- var $uses = array('Addon', 'AddonCollection', 'Addontype', 'Application', 'Collection', 'File', 'GlobalStat', 'Platform', 'Tag', 'Translation', /*'Review',*/ 'UpdateCount', 'Version');
+ var $uses = array('Addon', 'AddonCollection', 'Addontype', 'Application', 'Collection', 'File', 'GlobalStat', 'Platform', 'Category', 'Translation', /*'Review',*/ 'UpdateCount', 'Version');
var $components = array('Amo', 'Image', 'Pagination', 'Search', 'Session', 'Versioncompare');
var $helpers = array('Html', 'Link', 'Time', 'Localization', 'Ajax', 'Number', 'Pagination');
var $namedArgs = true;
@@ -354,7 +354,7 @@ class ApiController extends AppController
if ($listtype =='recommended') {
$sql .= ' UNION SELECT DISTINCT(f.addon_id)
FROM ';
- $tables2 = ' addons_tags AS f LEFT JOIN addons AS a ON f.addon_id = a.id ';
+ $tables2 = ' addons_categories AS f LEFT JOIN addons AS a ON f.addon_id = a.id ';
$where2 = ' WHERE f.feature = 1
AND a.status =\''.STATUS_PUBLIC.'\' ';
if ($list_os && $list_os != 'all' && $list_os != 'ALL'
@@ -472,11 +472,11 @@ class ApiController extends AppController
'conditions' => 'addons_users.listed=1',
'order' => 'addons_users.position'
),
- 'Tag' => array(
- 'className' => 'Tag',
- 'joinTable' => 'addons_tags',
+ 'Category' => array(
+ 'className' => 'Category',
+ 'joinTable' => 'addons_categories',
'foreignKey' => 'addon_id',
- 'associationForeignKey'=> 'tag_id'
+ 'associationForeignKey'=> 'category_id'
)
)
));
@@ -489,14 +489,14 @@ class ApiController extends AppController
)
));
- // Rather than trying to join tags and addon types in SQL, collect IDs
+ // Rather than trying to join categories and addon types in SQL, collect IDs
// and make a pair of queries to fetch them.
- $tag_ids = array();
+ $category_ids = array();
$addon_type_ids = array();
foreach ($addons_data as $addon) {
$addon_type_ids[$addon['Addon']['addontype_id']] = true;
- foreach ($addon['Tag'] as $tag)
- $tag_ids[$tag['id']] = true;
+ foreach ($addon['Category'] as $category)
+ $category_ids[$category['id']] = true;
}
// Query for addon types found in this set of addons, assemble a map
@@ -509,14 +509,14 @@ class ApiController extends AppController
$addon_types[$row['Addontype']['id']] = $row;
}
- // Query for addon types found in this set of tags, assemble a map
+ // Query for addon types found in this set of categories, assemble a map
// for an in-code join later.
- $tag_rows = $this->Tag->findAll(array(
- 'Tag.id' => array_keys($tag_ids)
+ $category_rows = $this->Category->findAll(array(
+ 'Category.id' => array_keys($category_ids)
));
- $all_tags = array();
- foreach ($tag_rows as $row) {
- $all_tags[$row['Tag']['id']] = $row;
+ $all_categories = array();
+ foreach ($category_rows as $row) {
+ $all_categories[$row['Category']['id']] = $row;
}
$app_names = $this->Application->getIDList();
@@ -530,7 +530,7 @@ class ApiController extends AppController
// Process addons list to produce a much flatter and more easily
// sanitized array structure for the view, sprinkling in details
- // like tags and version information along the way.
+ // like categories and version information along the way.
//
// TODO: Reconcile this with the _getAddons() method from which this
// was refactored but not replaced.
@@ -580,17 +580,17 @@ class ApiController extends AppController
'users' => $addon['User'],
'eula' => $addon['Translation']['eula']['string'],
'averagerating' => $addon['Addon']['averagerating'],
- 'tags' => array(),
+ 'categories' => array(),
'compatible_apps' => array(),
'all_compatible_os' => array(),
'fileinfo' => array()
);
- // Add the list of tags into the addon details
- foreach ($addon['Tag'] as $x) {
- $x = $all_tags[ $x['id'] ];
- $addon_out['tags'][] = array(
- 'id' => $x['Tag']['id'],
+ // Add the list of categories into the addon details
+ foreach ($addon['Category'] as $x) {
+ $x = $all_categories[ $x['id'] ];
+ $addon_out['categories'][] = array(
+ 'id' => $x['Category']['id'],
'name' => $x['Translation']['name']['string']
);
}
diff --git a/site/app/controllers/collections_controller.php b/site/app/controllers/collections_controller.php
index 0fe1e70..6db05b5 100644
--- a/site/app/controllers/collections_controller.php
+++ b/site/app/controllers/collections_controller.php
@@ -334,7 +334,7 @@ class CollectionsController extends AppController
// Fetch #3! Pull useful addon data this time.
$addons = $this->Addon->getAddonList($pagedIds,array(
- 'all_tags', 'authors', 'compatible_apps', 'files', 'latest_version',
+ 'all_categories', 'authors', 'compatible_apps', 'files', 'latest_version',
'list_details'));
foreach($addons as &$addon) {
diff --git a/site/app/controllers/components/amo.php b/site/app/controllers/components/amo.php
index fa24b1a..a600c29 100644
--- a/site/app/controllers/components/amo.php
+++ b/site/app/controllers/components/amo.php
@@ -337,7 +337,7 @@ class AmoComponent extends Object {
loadComponent('Versioncompare');
$versionCompare =& new VersioncompareComponent();
- $applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Tag')));
+ $applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Category')));
$applications = $applicationModel->findAll('Application.supported=1', null, null, null, null, 2);
$appvids = array();
$versions = array();
@@ -636,26 +636,26 @@ class AmoComponent extends Object {
/**
- * Get a list of tags in alphabetical order.
+ * Get a list of categories in alphabetical order.
*/
- function getTags($app=APP_ID,$type=ADDON_EXTENSION) {
+ function getCategories($app=APP_ID,$type=ADDON_EXTENSION) {
- if (!isset($this->controller->Tag)) {
- loadModel('Tag');
- $this->controller->Tag =& new Tag();
+ if (!isset($this->controller->Category)) {
+ loadModel('Category');
+ $this->controller->Category =& new Category();
// for CakePHP 1.2 this would be:
- // $this->controller->loadModel('Tag');
+ // $this->controller->loadModel('Category');
}
- $this->controller->Tag->unbindFully();
+ $this->controller->Category->unbindFully();
- return $this->controller->Tag->findAll(
+ return $this->controller->Category->findAll(
array(
'application_id' => $app,
'addontype_id' => $type
),
null,
- 'Tag.weight, Translation.name'
+ 'Category.weight, Translation.name'
);
}
@@ -713,20 +713,20 @@ class AmoComponent extends Object {
}
// add regular categories to list
- $tags = $this->getTags();
- foreach ($tags as $_tag) {
+ $categories = $this->getCategories();
+ foreach ($categories as $_category) {
/* support hybrid categories */
- if (isset($hybrid_categories[APP_ID][$_tag['Tag']['id']])) {
- $_type = $hybrid_categories[APP_ID][$_tag['Tag']['id']];
+ if (isset($hybrid_categories[APP_ID][$_category['Category']['id']])) {
+ $_type = $hybrid_categories[APP_ID][$_category['Category']['id']];
$_cat = 0;
} else {
- $_type = $_tag['Tag']['addontype_id'];
- $_cat = $_tag['Tag']['id'];
+ $_type = $_category['Category']['addontype_id'];
+ $_cat = $_category['Category']['id'];
}
- $_name = $_tag['Translation']['name']['string'];
- $_weight = $_tag['Tag']['weight'];
- $_count = $_tag['Tag']['count'];
+ $_name = $_category['Translation']['name']['string'];
+ $_weight = $_category['Category']['weight'];
+ $_count = $_category['Category']['count'];
// add item to results array
$catlist[] = array(
diff --git a/site/app/controllers/components/audit.php b/site/app/controllers/components/audit.php
index 2a2d0b3..b49e776 100644
--- a/site/app/controllers/components/audit.php
+++ b/site/app/controllers/components/audit.php
@@ -109,21 +109,21 @@ class AuditComponent extends Object {
}
break;
- case 'tag_create':
- case 'tag_edit':
- $tagInfo = $this->controller->Tag->findById($log['Eventlog']['changed_id'], null, null, -1);
- $tag = $this->link($tagInfo['Translation']['name']['string'], '/admin/tags');
+ case 'category_create':
+ case 'category_edit':
+ $categoryInfo = $this->controller->Category->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $category = $this->link($categoryInfo['Translation']['name']['string'], '/admin/categories');
- if ($log['Eventlog']['action'] == 'tag_create') {
- $entry = sprintf(___('audit_tag_create'), $user, $tag);
+ if ($log['Eventlog']['action'] == 'category_create') {
+ $entry = sprintf(___('audit_category_create'), $user, $category);
}
- elseif ($log['Eventlog']['action'] == 'tag_edit') {
- $entry = sprintf(___('audit_tag_edit'), $user, $tag);
+ elseif ($log['Eventlog']['action'] == 'category_edit') {
+ $entry = sprintf(___('audit_category_edit'), $user, $category);
}
break;
- case 'tag_delete':
- $entry = sprintf(___('audit_tag_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
+ case 'category_delete':
+ $entry = sprintf(___('audit_category_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
break;
case 'platform_create':
@@ -266,8 +266,8 @@ class AuditComponent extends Object {
$entry = sprintf(___('audit_update_applications'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/applications/?userlang="));
break;
- case 'update_tags':
- $entry = sprintf(___('audit_update_tags'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/tags/?userlang="));
+ case 'update_categories':
+ $entry = sprintf(___('audit_update_categories'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/categories/?userlang="));
break;
case 'update_platforms':
diff --git a/site/app/controllers/components/developers.php b/site/app/controllers/components/developers.php
index 15ae6b8..c109059 100644
--- a/site/app/controllers/components/developers.php
+++ b/site/app/controllers/components/developers.php
@@ -48,21 +48,21 @@ class DevelopersComponent extends Object {
}
/**
- * Make sure at least one but no more than 5 tags selected
- * @param array $tags post data of selected tags
+ * Make sure at least one but no more than 5 categories selected
+ * @param array $categories post data of selected categories
*/
- function validateTags($tags) {
+ function validateCategories($categories) {
$errors =& $this->controller->Error;
- //Must have at least one tag selected, but no more than 5
- if (empty($tags)) {
- $errors->addError(_('devcp_error_one_category'), 'Tag/Tag');
- $this->controller->Tag->invalidate('Tag');
+ //Must have at least one category selected, but no more than 5
+ if (empty($categories)) {
+ $errors->addError(_('devcp_error_one_category'), 'Category/Category');
+ $this->controller->Category->invalidate('Category');
return false;
}
- elseif (count($tags) > 5) {
- $errors->addError(_('devcp_error_five_categories'), 'Tag/Tag');
- $this->controller->Tag->invalidate('Tag');
+ elseif (count($categories) > 5) {
+ $errors->addError(_('devcp_error_five_categories'), 'Category/Category');
+ $this->controller->Category->invalidate('Category');
return false;
}
@@ -115,23 +115,23 @@ class DevelopersComponent extends Object {
}
/**
- * Get all tags for an addontype
+ * Get all categories for an addontype
* @param int $addontypeId the addontype ID
* @param array $applicationIds the ids of supported applications
- * @return array $tags the tags
+ * @return array $categories the categories
*/
- function getTags($addontypeId, $applicationIds) {
- //Get tags based on addontype
- $applicationIdQry = !empty($applicationIds) ? "Tag.application_id IN (".implode(', ', $applicationIds).") OR" : '';
+ function getCategories($addontypeId, $applicationIds) {
+ //Get categories based on addontype
+ $applicationIdQry = !empty($applicationIds) ? "Category.application_id IN (".implode(', ', $applicationIds).") OR" : '';
// Override for search engines. They have no application restrictions (bug 417727)
if ($addontypeId == ADDON_SEARCH) {
- $applicationIdQry = 'Tag.application_id IS NOT NULL OR';
+ $applicationIdQry = 'Category.application_id IS NOT NULL OR';
}
- $tagsQry = $this->controller->Tag->findAll("Tag.addontype_id='{$addontypeId}' AND ({$applicationIdQry} Tag.application_id IS NULL)");
+ $categoriesQry = $this->controller->Category->findAll("Category.addontype_id='{$addontypeId}' AND ({$applicationIdQry} Category.application_id IS NULL)");
- if ($tagsQry) {
+ if ($categoriesQry) {
// show (APP) behind name?
$add_apps = (is_array($applicationIds) && count($applicationIds)>1);
if ($add_apps) {
@@ -144,46 +144,46 @@ class DevelopersComponent extends Object {
}
}
- foreach ($tagsQry as $k => $v) {
- $tags['names'][$v['Tag']['id']] = $v['Translation']['name']['string'];
- if ($add_apps && !is_null($v['Tag']['application_id']))
- $tags['names'][$v['Tag']['id']] .= " ({$appnames[$v['Tag']['application_id']]})";
- $tags['descriptions'][] = $v['Tag']['id'].': "'.addslashes($v['Translation']['description']['string']).'"';
+ foreach ($categoriesQry as $k => $v) {
+ $categories['names'][$v['Category']['id']] = $v['Translation']['name']['string'];
+ if ($add_apps && !is_null($v['Category']['application_id']))
+ $categories['names'][$v['Category']['id']] .= " ({$appnames[$v['Category']['application_id']]})";
+ $categories['descriptions'][] = $v['Category']['id'].': "'.addslashes($v['Translation']['description']['string']).'"';
}
}
- if (!empty($tags)) {
- asort($tags['names']);
- return $tags;
+ if (!empty($categories)) {
+ asort($categories['names']);
+ return $categories;
}
return array();
}
/**
- * Get all selected tags in order of post data, existing data, default
- * @param array $currentTags currently selected tags
- * @return array $selectedTags the selected tags
+ * Get all selected categories in order of post data, existing data, default
+ * @param array $currentCategories currently selected categories
+ * @return array $selectedCategories the selected categories
*/
- function getSelectedTags($currentTags) {
+ function getSelectedCategories($currentCategories) {
//post data
- if (!empty($this->controller->data['Tag']['Tag'])) {
- foreach($this->controller->data['Tag']['Tag'] as $tag) {
- $selectedTags[] = $tag;
+ if (!empty($this->controller->data['Category']['Category'])) {
+ foreach($this->controller->data['Category']['Category'] as $category) {
+ $selectedCategories[] = $category;
}
}
//current data
- elseif (!empty($currentTags)) {
- foreach ($currentTags as $tag) {
- $selectedTags[] = $tag['id'];
+ elseif (!empty($currentCategories)) {
+ foreach ($currentCategories as $category) {
+ $selectedCategories[] = $category['id'];
}
}
//default data
else {
- $selectedTags = array();
+ $selectedCategories = array();
}
- return $selectedTags;
+ return $selectedCategories;
}
/**
@@ -864,7 +864,7 @@ class DevelopersComponent extends Object {
/**
* Delete an addon, along with its versions, files, reviews, previews,
- * favorites, features, tags, and translations
+ * favorites, features, categories, and translations
* @param int $id the add-on id
* @return boolean
*/
@@ -893,8 +893,8 @@ class DevelopersComponent extends Object {
}
}
- //Delete addons_tags rows
- $this->controller->Addon->execute("DELETE FROM addons_tags WHERE addon_id='{$id}'");
+ //Delete addons_categories rows
+ $this->controller->Addon->execute("DELETE FROM addons_categories WHERE addon_id='{$id}'");
//Delete addons_users rows
$this->controller->Addon->execute("DELETE FROM addons_users WHERE addon_id='{$id}'");
diff --git a/site/app/controllers/components/pagination.php b/site/app/controllers/components/pagination.php
index a6f6685..a571633 100644
--- a/site/app/controllers/components/pagination.php
+++ b/site/app/controllers/components/pagination.php
@@ -460,7 +460,7 @@ class PaginationComponent extends Object
{
if (isset($_GET[$parameter]))
{
- $this->paging[$field] = $this->Sanitize->paranoid($_GET[$parameter]);
+ $this->paging[$field] = $this->Sanitize->cleanValue($_GET[$parameter]);
}
else
{
diff --git a/site/app/controllers/components/search.php b/site/app/controllers/components/search.php
index 20f25ab..1bafee1 100644
--- a/site/app/controllers/components/search.php
+++ b/site/app/controllers/components/search.php
@@ -127,9 +127,9 @@ class SearchComponent extends Object {
* @param locale controls whether we search within only the current locale and en-US (faster) or all locales
* @return array of information about results (modified cake results)
*/
- function search($terms, $searchtype=NULL, $category=0, $status=NULL,
+ function search($terms, $tag=null, $searchtype=NULL, $category=0, $status=NULL,
$lver = -1, $hver = -1, $vfuz =false, $atype = ADDON_ANY,
- $platform= PLATFORM_ANY, $lup = "", $sort = "", $locale=false) {
+ $platform= PLATFORM_ANY, $lup = "", $sort = "", $locale=false ) {
global $valid_status, $hybrid_categories, $app_listedtypes;
if (isset($status)) {
@@ -151,7 +151,7 @@ class SearchComponent extends Object {
/* prepare SQL query */
// fields to search in
- $fields = array('name', 'summary', 'description');
+ $fields = array('name', 'summary', 'description', 'tags');
$_termarray = array();
// first prepare text terms
@@ -178,6 +178,11 @@ class SearchComponent extends Object {
$text_score = " MATCH(a.".implode(', a.',$fields).") AGAINST ('".implode(" ", $_termarray)."')";
$boolean_score = " MATCH(a.".implode(', a.',$fields).") AGAINST ('".implode(" ", $_search_termarray)."' IN BOOLEAN MODE)";
+ if( $tag != null ) {
+ $boolean_score .= " AND MATCH(a.".implode(', a.', array('tags')).") AGAINST ('".implode(" ", array($tag))."' IN BOOLEAN MODE) ";
+ }
+
+
} else { //in this case enumerate all addons. this allows advanced search to act as a filter
$text_score = "TRUE";
$boolean_score = "TRUE";
@@ -240,14 +245,14 @@ class SearchComponent extends Object {
if ($category > 0) {
if (!isset($hybrid_categories[APP_ID][$category])) {
// regular category restriction
- $_joins[] = "INNER JOIN addons_tags AS atags ON (atags.addon_id = id AND atags.tag_id = '{$category}')";
+ $_joins[] = "INNER JOIN addons_categories AS acategories ON (acategories.addon_id = id AND acategories.category_id = '{$category}')";
} else {
// hybrid category
$_hybrid_type = $hybrid_categories[APP_ID][$category];
if (!in_array($_hybrid_type, $_addon_types)) $_addon_types[] = $_hybrid_type;
- $_joins[] = "LEFT JOIN addons_tags AS atags ON (atags.addon_id = id AND atags.tag_id = '{$category}')";
- $_where[] = "(a.addontype = ".$_hybrid_type." OR atags.tag_id IS NOT NULL)";
+ $_joins[] = "LEFT JOIN addons_categories AS acategories ON (acategories.addon_id = id AND acategories.category_id = '{$category}')";
+ $_where[] = "(a.addontype = ".$_hybrid_type." OR acategories.category_id IS NOT NULL)";
}
}
@@ -348,6 +353,8 @@ class SearchComponent extends Object {
.(empty($_where) ? '' : 'AND ('.implode(' AND ', $_where).') ')
."ORDER BY ".implode(', ', $_orderby);
+ //echo '<br><br>sql='.$sql;
+
// query the db and return the ids found
$_results = $this->controller->Addon->query($sql, true);
@@ -394,6 +401,7 @@ class SearchComponent extends Object {
$text_score = " MATCH(c.".implode(', c.',$fields).") AGAINST ('".implode(" ", $_termarray)."')";
$boolean_score = " MATCH(c.".implode(', c.',$fields).") AGAINST ('".implode(" ", $_search_termarray)."' IN BOOLEAN MODE)";
+
} else { //in this case enumerate all collections. this allows advanced search to act as a filter
$text_score = "TRUE";
$boolean_score = "TRUE";
@@ -445,6 +453,9 @@ class SearchComponent extends Object {
WHERE {$_matches}
".(empty($_where) ? '' : 'AND ('.implode(' AND ', $_where).') ')."
ORDER BY ".implode(', ', $_orderby);
+
+
+
$_results = $this->controller->Addon->query($sql, true);
// return the ids found
diff --git a/site/app/controllers/developers_controller.php b/site/app/controllers/developers_controller.php
index 308ea36..708a04a 100644
--- a/site/app/controllers/developers_controller.php
+++ b/site/app/controllers/developers_controller.php
@@ -60,7 +60,7 @@ function getitem($object, $name, $default=null) {
class DevelopersController extends AppController
{
var $name = 'Developers';
- var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion',
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion','Category',
'EditorSubscription', 'Eventlog', 'File', 'License', 'Platform', 'Preview', 'Review',
'Tag', 'Translation', 'User', 'Version');
var $components = array('Amo', 'Developers', 'Editors', 'Email', 'Error',
@@ -612,6 +612,10 @@ class DevelopersController extends AppController
case 'authors':
$this->setAction('_editAddonAuthors', $addon_id);
+ break;
+
+ case 'tags':
+ $this->setAction('_editAddonTags', $addon_id);
break;
default:
@@ -719,8 +723,8 @@ class DevelopersController extends AppController
function _editAddonCategories($addon_id) {
// Save categories if POST data
- if (!empty($this->data['Tag']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
- $this->Tag->saveCategories($addon_id, $this->data['Tag']);
+ if (!empty($this->data['Category']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ $this->Category->saveCategories($addon_id, $this->data['Category']);
// flush cached add-on objects
if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
@@ -744,57 +748,93 @@ class DevelopersController extends AppController
$supportedApps = $this->Addon->getApplicationsEverSupported($addon_id);
}
- // All tags for add-on's type and supported applications
- $tagDescriptions = array();
- $sortedTags = array();
+ // All categories for add-on's type and supported applications
+ $categoryDescriptions = array();
+ $sortedCategories = array();
if (!empty($supportedApps)) {
foreach ($supportedApps as $supportedApp) {
- $tags = $this->Tag->findAll("Tag.addontype_id={$addon['Addon']['addontype_id']} AND Tag.application_id={$supportedApp['Application']['id']}");
+ $categories = $this->Category->findAll("Category.addontype_id={$addon['Addon']['addontype_id']} AND Category.application_id={$supportedApp['Application']['id']}");
$sorted = array();
- if (!empty($tags)) {
- foreach ($tags as $tag) {
- $sorted[$tag['Tag']['id']] = $tag['Translation']['name']['string'];
- $tagDescriptions[$tag['Tag']['id']] = $tag['Translation']['description']['string'];
+ if (!empty($categories)) {
+ foreach ($categories as $category) {
+ $sorted[$category['Category']['id']] = $category['Translation']['name']['string'];
+ $categoryDescriptions[$category['Category']['id']] = $category['Translation']['description']['string'];
}
asort($sorted);
}
- $sortedTags[$supportedApp['Application']['id']] = $sorted;
+ $sortedCategories[$supportedApp['Application']['id']] = $sorted;
}
}
- $this->set('sortedTags', $sortedTags);
- $this->set('tagDescriptions', $tagDescriptions);
+ $this->set('sortedCategories', $sortedCategories);
+ $this->set('categoryDescriptions', $categoryDescriptions);
- // Currently selected tags
- $currentTags = array();
- if (!empty($addon['Tag'])) {
- foreach ($addon['Tag'] as $tag) {
- $currentTags[] = $tag['id'];
+ // Currently selected categories
+ $currentCategories = array();
+ if (!empty($addon['Category'])) {
+ foreach ($addon['Category'] as $category) {
+ $currentCategories[] = $category['id'];
}
}
- $this->publish('currentTags', $currentTags);
+ $this->publish('currentCategories', $currentCategories);
$this->publish('applications', $this->Application->getIDList());
// The "Other" category for each application that has one
if ($addon['Addon']['addontype_id'] == ADDON_SEARCH) {
- $otherTags = array(
+ $otherCategories = array(
1 => 82
);
}
else {
- $otherTags = array(
+ $otherCategories = array(
1 => 73,
59 => 49,
18 => 50,
);
}
- $this->publish('otherTags', $otherTags);
+ $this->publish('otherCategories', $otherCategories);
$this->render('addon_edit_categories');
}
+
+ function _editAddonTags($addon_id) {
+ $this->publish('jsAdd', array('tags.js'));
+
+ // Save tags if POST data
+ if (!empty($this->data['Tag']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ // Add tags here
+
+
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ $this->publish('success', true);
+ }
+
+ $addon_data = $this->Addon->findById($addon_id);
+ $this->publish('addon_data',$addon_data);
+
+ // MAke the tag list, passing in this addon and the currently logged in user
+ $loggedIn = $this->Session->check('User')? true : false;
+ $this->set('loggedIn', $loggedIn);
+ if ($loggedIn) { $user=$this->Session->read('User'); } else { $user=null; }
+
+ // Get all tags
+ $tags = $this->Tag->makeTagList($addon_data, $user);
+
+ $this->publish('userTags', $tags['userTags']);
+ $this->publish('developerTags', $tags['developerTags']);
+ $this->publish('addon_id', $addon_data['Addon']['id']);
+
+ $this->render('addon_edit_tags');
+ }
+
+
+
+
/**
* Edit Add-on Authors
@@ -884,7 +924,7 @@ class DevelopersController extends AppController
$criteria['name'] = !empty($addon['Translation']['name']['string']);
$criteria['summary'] = !empty($addon['Translation']['summary']['string']);
$criteria['description'] = !empty($addon['Translation']['description']['string']);
- $criteria['category'] = !empty($addon['Tag']);
+ $criteria['category'] = !empty($addon['Category']);
$criteria['previews'] = !empty($previews);
$criteria['prerelease'] = !empty($addon['Addon']['prerelease']) ? false : true;
diff --git a/site/app/controllers/editors_controller.php b/site/app/controllers/editors_controller.php
index 87cf982..545567a 100644
--- a/site/app/controllers/editors_controller.php
+++ b/site/app/controllers/editors_controller.php
@@ -43,9 +43,9 @@
class EditorsController extends AppController
{
var $name = 'Editors';
- var $uses = array('Addon', 'AddonTag', 'Addontype', 'Application', 'Approval',
+ var $uses = array('Addon', 'AddonCategory', 'Addontype', 'Application', 'Approval',
'Appversion', 'Cannedresponse', 'EditorSubscription', 'Eventlog', 'Favorite',
- 'File', 'Platform', 'Review', 'ReviewsModerationFlag', 'Tag', 'Translation',
+ 'File', 'Platform', 'Review', 'ReviewsModerationFlag', 'Category', 'Translation',
'User', 'Version');
var $components = array('Amo', 'Audit', 'Developers', 'Editors', 'Email', 'Error', 'Image', 'Pagination');
var $helpers = array('Html', 'Javascript', 'Ajax', 'Listing', 'Localization', 'Pagination');
@@ -305,14 +305,14 @@ class EditorsController extends AppController
$this->pageTitle = $addon['Translation']['name']['string'] . ' :: ' . $this->pageTitle;
- if (!empty($addon['Tag'])) {
- foreach ($addon['Tag'] as $tag) {
- $tags[] = $tag['id'];
+ if (!empty($addon['Category'])) {
+ foreach ($addon['Category'] as $category) {
+ $categories[] = $category['id'];
}
- $addon['Tags'] = $this->Tag->findAll("Tag.id IN (".implode(', ', $tags).")");
+ $addon['Categories'] = $this->Category->findAll("Category.id IN (".implode(', ', $categories).")");
}
else
- $addon['Tags'] = array();
+ $addon['Categories'] = array();
$platforms = $this->Amo->getPlatformName();
@@ -1378,7 +1378,7 @@ class EditorsController extends AppController
$this->data['Addon']['id'] = $matches[1];
}
- if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Tag']['id'])) {
+ if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Category']['id'])) {
header('HTTP/1.1 400 Bad Request');
$this->flash(_('editors_featured_addon_add_failure'), '/editors/featured');
return;
@@ -1392,9 +1392,9 @@ class EditorsController extends AppController
}
// If the add-on isn't in the category, we'll add it.
- $_new_feature_query = "REPLACE INTO addons_tags (addon_id, tag_id, feature) VALUES ( '{$this->data['Addon']['id']}', '{$this->data['Tag']['id']}', 1)";
+ $_new_feature_query = "REPLACE INTO addons_categories (addon_id, category_id, feature) VALUES ( '{$this->data['Addon']['id']}', '{$this->data['Category']['id']}', 1)";
- if ($this->AddonTag->query($_new_feature_query)) {
+ if ($this->AddonCategory->query($_new_feature_query)) {
header('HTTP/1.1 400 Bad Request');
$this->flash(_('editors_featured_addon_add_failure'), '/editors/featured');
} else {
@@ -1406,15 +1406,15 @@ class EditorsController extends AppController
case 'edit':
global $valid_languages;
- if (!empty($this->data['AddonTag']['feature_locales'])) {
- if (count(array_diff(explode(',',$this->data['AddonTag']['feature_locales']), array_keys($valid_languages))) > 0) {
+ if (!empty($this->data['AddonCategory']['feature_locales'])) {
+ if (count(array_diff(explode(',',$this->data['AddonCategory']['feature_locales']), array_keys($valid_languages))) > 0) {
header('HTTP/1.1 400 Bad Request');
$this->flash(_('editors_featured_addon_invalid_locale'), '/editors/featured');
return;
}
}
- if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Tag']['id']) || preg_match('/[^A-Za-z,-]/',$this->data['AddonTag']['feature_locales'])) {
+ if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Category']['id']) || preg_match('/[^A-Za-z,-]/',$this->data['AddonCategory']['feature_locales'])) {
header('HTTP/1.1 400 Bad Request');
$this->flash(_('editors_featured_addon_edit_failure'), '/editors/featured');
return;
@@ -1423,16 +1423,16 @@ class EditorsController extends AppController
$this->Eventlog->log($this, 'editor', 'feature_locale_change', 'feature-locales', $this->data['Addon']['id']);
// Reorder the locales
- $_locales = array_unique(explode(',', $this->data['AddonTag']['feature_locales']));
+ $_locales = array_unique(explode(',', $this->data['AddonCategory']['feature_locales']));
sort($_locales);
- $this->data['AddonTag']['feature_locales'] = implode(',',$_locales);
+ $this->data['AddonCategory']['feature_locales'] = implode(',',$_locales);
- $_edit_feature_query = "UPDATE addons_tags
- SET feature_locales='{$this->data['AddonTag']['feature_locales']}'
+ $_edit_feature_query = "UPDATE addons_categories
+ SET feature_locales='{$this->data['AddonCategory']['feature_locales']}'
WHERE addon_id='{$this->data['Addon']['id']}'
- AND tag_id='{$this->data['Tag']['id']}'";
+ AND category_id='{$this->data['Category']['id']}'";
- if ($this->AddonTag->query($_edit_feature_query)) {
+ if ($this->AddonCategory->query($_edit_feature_query)) {
header('HTTP/1.1 400 Bad Request');
$this->flash(_('editors_featured_addon_edit_failure'), '/editors/featured');
} else {
@@ -1441,12 +1441,12 @@ class EditorsController extends AppController
return;
case 'remove':
- if (is_numeric($this->data['Tag']['id']) && is_numeric($this->data['Addon']['id'])) {
+ if (is_numeric($this->data['Category']['id']) && is_numeric($this->data['Addon']['id'])) {
$this->Eventlog->log($this, 'editor', 'feature_remove', null, $this->data['Addon']['id'], null, $this->data['Addon']['id']);
// Neither query() nor execute() return success from a DELETE call, even when the row is deleted. wtf.
- $this->AddonTag->execute("DELETE FROM `addons_tags` WHERE addon_id='{$this->data['Addon']['id']}' AND tag_id='{$this->data['Tag']['id']}' AND feature=1 LIMIT 1");
+ $this->AddonCategory->execute("DELETE FROM `addons_categories` WHERE addon_id='{$this->data['Addon']['id']}' AND category_id='{$this->data['Category']['id']}' AND feature=1 LIMIT 1");
// Assume we succeeded
$this->flash(_('editors_featured_addon_remove_success'), '/editors/featured', 3);
@@ -1468,11 +1468,11 @@ class EditorsController extends AppController
$this->publish('subpagetitle', _('editors_featured_addons_pagetitle'));
// Get all featured Addons
- $features = $this->AddonTag->findAllByFeature(1, array('addon_id'));
- $_addon_ids = $addons_by_tag = array();
+ $features = $this->AddonCategory->findAllByFeature(1, array('addon_id'));
+ $_addon_ids = $addons_by_category = array();
if (!empty($features)) {
- foreach ($features as $feature) { $_addon_ids[] = $feature['AddonTag']['addon_id']; }
+ foreach ($features as $feature) { $_addon_ids[] = $feature['AddonCategory']['addon_id']; }
$_addon_ids = array_unique($_addon_ids);
// Big ol' array
@@ -1481,12 +1481,12 @@ class EditorsController extends AppController
foreach ($features as $feature) {
// Dump them into the array sorted by category
- foreach ($feature['AddonTag'] as $attributes) {
+ foreach ($feature['AddonCategory'] as $attributes) {
if ($attributes['feature'] == 1) {
- // override the AddonTag array for the view. Even though an add-on will have multiple tags, we only want one for this view
- $feature['AddonTag'] = array( 0 => $attributes );
+ // override the AddonCategory array for the view. Even though an add-on will have multiple categories, we only want one for this view
+ $feature['AddonCategory'] = array( 0 => $attributes );
- $addons_by_tag[$attributes['tag_id']][] = $feature;
+ $addons_by_category[$attributes['category_id']][] = $feature;
}
}
@@ -1494,17 +1494,17 @@ class EditorsController extends AppController
}
}
- // Reorganize the tags so it's easier to use them in the view. TheLittleThingsWearMeDown++ :(
- $tags = array();
- foreach ($this->Tag->findAll('', null, array('Tag.application_id', 'Tag.addontype_id', 'Translation.name')) as $tag) {
- $tags[$tag['Tag']['id']] = $tag;
+ // Reorganize the categories so it's easier to use them in the view. TheLittleThingsWearMeDown++ :(
+ $categories = array();
+ foreach ($this->Category->findAll('', null, array('Category.application_id', 'Category.addontype_id', 'Translation.name')) as $category) {
+ $categories[$category['Category']['id']] = $category;
}
$this->set('applications', $this->Amo->getApplicationName());
$this->set('addontypes', $this->Addontype->getNames());
- $this->set('tags', $tags);
+ $this->set('categories', $categories);
$this->set('mode', 'featured');
- $this->publish('addons_by_tag', $addons_by_tag);
+ $this->publish('addons_by_category', $addons_by_category);
$this->render('featured');
}
diff --git a/site/app/controllers/facebook_controller.php b/site/app/controllers/facebook_controller.php
index 30ea0c6..0fc95f1 100644
--- a/site/app/controllers/facebook_controller.php
+++ b/site/app/controllers/facebook_controller.php
@@ -42,7 +42,7 @@ class FacebookController extends AppController
{
var $name = 'Facebook';
var $beforeFilter = array('checkCSRF', 'getNamedArgs');
- var $uses = array('Addon', 'Application', 'FacebookData', 'FacebookFavorite', 'FacebookSession', 'FacebookUser', 'File', 'Preview', 'Tag', 'User', 'Version');
+ var $uses = array('Addon', 'Application', 'FacebookData', 'FacebookFavorite', 'FacebookSession', 'FacebookUser', 'File', 'Preview', 'Category', 'User', 'Version');
var $components = array('Amo', 'Image', 'Newsfeed', 'Search');
var $helpers = array('Html', 'Facebook');
@@ -335,25 +335,25 @@ class FacebookController extends AppController
}
if ($type == ADDON_EXTENSION || (is_array($type) && in_array(ADDON_EXTENSION, $type))) {
- // Extension tags
- if ($extension_tags = $this->Tag->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_EXTENSION))) {
- foreach ($extension_tags as $extension_tag) {
- $tags[$extension_tag['Tag']['id']] = (is_array($type) ? 'Extensions: ' : '').$extension_tag['Translation']['name']['string'];
+ // Extension categories
+ if ($extension_categories = $this->Category->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_EXTENSION))) {
+ foreach ($extension_categories as $extension_category) {
+ $categories[$extension_category['Category']['id']] = (is_array($type) ? 'Extensions: ' : '').$extension_category['Translation']['name']['string'];
}
}
}
if ($type == ADDON_THEME || (is_array($type) && in_array(ADDON_THEME, $type))) {
- // Theme tags
- if ($theme_tags = $this->Tag->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_THEME))) {
- foreach ($theme_tags as $theme_tag) {
- $tags[$theme_tag['Tag']['id']] = (is_array($type) ? 'Themes: ' : '').$theme_tag['Translation']['name']['string'];
+ // Theme categories
+ if ($theme_categories = $this->Category->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_THEME))) {
+ foreach ($theme_categories as $theme_category) {
+ $categories[$theme_category['Category']['id']] = (is_array($type) ? 'Themes: ' : '').$theme_category['Translation']['name']['string'];
}
}
}
- $tags[0] = ' Filter by Category';
- asort($tags);
- $this->set('tags', $tags);
+ $categories[0] = ' Filter by Category';
+ asort($categories);
+ $this->set('categories', $categories);
$this->set('addons', $addons);
$this->set('count', $count);
diff --git a/site/app/controllers/localizers_controller.php b/site/app/controllers/localizers_controller.php
index e49bb48..1acdee1 100644
--- a/site/app/controllers/localizers_controller.php
+++ b/site/app/controllers/localizers_controller.php
@@ -38,7 +38,8 @@
class LocalizersController extends AppController
{
var $name = 'Localizers';
- var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'CollectionFeatures', 'Eventlog', 'Platform','Tag', 'Translation', 'User', 'Version');
+
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'CollectionFeatures', 'Eventlog', 'Platform','Category', 'Translation', 'User', 'Version');
var $components = array('Amo', 'Audit', 'Error', 'Pagination');
var $helpers = array('Html', 'Javascript', 'Pagination');
@@ -153,14 +154,14 @@ class LocalizersController extends AppController
}
}
- //Pull tag translation ids
- if ($tags = $this->Tag->query("SELECT name, description FROM tags")) {
- foreach ($tags as $tag) {
- if (!empty($tag['tags']['name'])) {
- $ids[] = $tag['tags']['name'];
+ //Pull category translation ids
+ if ($categories = $this->Category->query("SELECT name, description FROM categories")) {
+ foreach ($categories as $category) {
+ if (!empty($category['categories']['name'])) {
+ $ids[] = $category['categories']['name'];
}
- if (!empty($tag['tags']['description'])) {
- $ids[] = $tag['tags']['description'];
+ if (!empty($category['categories']['description'])) {
+ $ids[] = $category['categories']['description'];
}
}
}
@@ -239,42 +240,42 @@ class LocalizersController extends AppController
/**
* Category Localization
*/
- function tags() {
- $this->breadcrumbs['Tag Localization'] = '/localizers/tags';
+ function categories() {
+ $this->breadcrumbs['Category Localization'] = '/localizers/categories';
$this->set('breadcrumbs', $this->breadcrumbs);
- if (!empty($this->data['Tag'])) {
+ if (!empty($this->data['Category'])) {
//Make sure user has write access
if (!$this->writeAccess) {
//Log
$this->Eventlog->log($this, 'security', 'modify_other_locale', null, 1, null, null, USERLANG);
- $this->flash('You do not have permission to modify this locale!', '/localizers/tags');
+ $this->flash('You do not have permission to modify this locale!', '/localizers/categories');
return;
}
- $this->Tag->setLang(USERLANG, $this);
- foreach ($this->data['Tag'] as $id => $data) {
- $this->Tag->id = $id;
- $this->Tag->save($data);
+ $this->Category->setLang(USERLANG, $this);
+ foreach ($this->data['Category'] as $id => $data) {
+ $this->Category->id = $id;
+ $this->Category->save($data);
}
//Log l10n action
- $this->Eventlog->log($this, 'l10n', 'update_tags', null, 1, null, null, USERLANG);
+ $this->Eventlog->log($this, 'l10n', 'update_categories', null, 1, null, null, USERLANG);
- $this->flash('Translations updated!', '/localizers/tags');
+ $this->flash('Translations updated!', '/localizers/categories');
return;
}
- $this->Tag->setLang(USERLANG, $this);
- $tags[USERLANG] = $this->Tag->findAll(null, null, null, null, null, 0);
+ $this->Category->setLang(USERLANG, $this);
+ $categories[USERLANG] = $this->Category->findAll(null, null, null, null, null, 0);
- $this->Tag->setLang('en-US', $this);
- $tags['en-US'] = $this->Tag->findAll(null, null, null, null, null, 0);
+ $this->Category->setLang('en-US', $this);
+ $categories['en-US'] = $this->Category->findAll(null, null, null, null, null, 0);
- $this->set('tags', $tags);
- $this->set('page', 'tags');
- $this->render('tags');
+ $this->set('categories', $categories);
+ $this->set('page', 'categories');
+ $this->render('categories');
}
/**
diff --git a/site/app/controllers/search_controller.php b/site/app/controllers/search_controller.php
index 5c0f524..21ffeb7 100644
--- a/site/app/controllers/search_controller.php
+++ b/site/app/controllers/search_controller.php
@@ -73,6 +73,7 @@ class SearchController extends AppController
var $securityLevel = 'low';
+
/**
* Constructor. Declared so we can initialize Sanitize.
*
@@ -85,6 +86,7 @@ class SearchController extends AppController
}
function beforeFilter() {
+ $this->publish('jsAdd', array('amo2009/collections'));
$this->forceShadowDb();
@@ -140,7 +142,14 @@ class SearchController extends AppController
} else
$category = array(0,0);
$this->publish('category', $category);
-
+
+ if (!empty($this->params['url']['tag'])) {
+ $_tag = $this->params['url']['tag'];
+ } else {
+ $_tag = null;
+ }
+ $this->publish('tag', $_tag);
+
//if advanced search atype set, use it.
$atype = -1;
$addon_types = $this->Addontype->getNames();
@@ -184,26 +193,27 @@ class SearchController extends AppController
$this->publish('vfuz', $vfuz);
// execute this search
- $_result_ids = $this->Search->search($_terms, $category[0], $category[1], NULL, $lver, $hver, $vfuz, $atype, $pid, $lup, $sort);
+ $_result_ids = $this->Search->search($_terms, $_tag, $category[0], $category[1], NULL, $lver, $hver, $vfuz, $atype, $pid, $lup, $sort);
if ($this->params['action'] != 'rss') {
$this->pageTitle = _('search_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
$this->publish('cssAdd', array('forms'));
$this->params['url']['q'] = urlencode( $this->params['url']['q']);
-
$this->Pagination->total = count($_result_ids);
-
+ $this->publish("total_count",$this->Pagination->total);
//if advanced search pagination set, use it.
$pp= 20;
if (isset( $this->params['url']['pp']) && in_array($this->params['url']['pp'], $this->Pagination->resultsPerPage)) {
$pp = $this->Pagination->show = $this->params['url']['pp'];
}
$this->publish('pp', $pp); //publish for element caching
-
+
list($order,$limit,$page) = $this->Pagination->init();
-
+
+ $this->publish("on_page", $page);
// cut the appropriate slice out of the results array
$offset = ($page-1)*$limit;
+ $this->publish("offset",$offset);
$_result_ids = array_slice($_result_ids, $offset, $limit);
if (!empty($_terms)) {
diff --git a/site/app/controllers/sharing_api_controller.php b/site/app/controllers/sharing_api_controller.php
index 1827959..715c2ef 100644
--- a/site/app/controllers/sharing_api_controller.php
+++ b/site/app/controllers/sharing_api_controller.php
@@ -57,7 +57,7 @@ class SharingApiController extends AppController
);
var $uses = array(
'Addon', 'AddonCollection', 'Addontype', 'ApiAuthToken',
- 'Application', 'Collection', 'File', 'Platform', 'Tag', 'Translation',
+ 'Application', 'Collection', 'File', 'Platform', 'Category', 'Translation',
'UpdateCount', 'Version'
);
var $components = array(
@@ -1003,11 +1003,11 @@ class SharingApiController extends AppController
'conditions' => 'addons_users.listed=1',
'order' => 'addons_users.position'
),
- 'Tag' => array(
- 'className' => 'Tag',
- 'joinTable' => 'addons_tags',
+ 'Category' => array(
+ 'className' => 'Category',
+ 'joinTable' => 'addons_categories',
'foreignKey' => 'addon_id',
- 'associationForeignKey'=> 'tag_id'
+ 'associationForeignKey'=> 'category_id'
)
)
));
@@ -1023,16 +1023,16 @@ class SharingApiController extends AppController
$addons_data = $this->Addon->findAll($conditions);
- // Rather than trying to join tags and addon types in SQL, collect IDs
+ // Rather than trying to join categories and addon types in SQL, collect IDs
// and make a pair of queries to fetch them.
- $tag_ids = array();
+ $category_ids = array();
$addon_type_ids = array();
$addon_ids = array();
foreach ($addons_data as $addon) {
$addon_ids[] = $addon['Addon']['id'];
$addon_type_ids[$addon['Addon']['addontype_id']] = true;
- foreach ($addon['Tag'] as $tag)
- $tag_ids[$tag['id']] = true;
+ foreach ($addon['Category'] as $category)
+ $category_ids[$category['id']] = true;
}
$user_names = array();
@@ -1065,14 +1065,14 @@ class SharingApiController extends AppController
$addon_types[$row['Addontype']['id']] = $row;
}
- // Query for addon types found in this set of tags, assemble a map
+ // Query for addon types found in this set of categories, assemble a map
// for an in-code join later.
- $tag_rows = $this->Tag->findAll(array(
- 'Tag.id' => array_keys($tag_ids)
+ $category_rows = $this->Category->findAll(array(
+ 'Category.id' => array_keys($category_ids)
));
- $all_tags = array();
- foreach ($tag_rows as $row) {
- $all_tags[$row['Tag']['id']] = $row;
+ $all_categories = array();
+ foreach ($category_rows as $row) {
+ $all_categories[$row['Category']['id']] = $row;
}
$app_names = $this->Application->getIDList();
@@ -1089,7 +1089,7 @@ class SharingApiController extends AppController
// Process addons list to produce a much flatter and more easily
// sanitized array structure for the view, sprinkling in details
- // like tags and version information along the way.
+ // like categories and version information along the way.
$addons_out = array();
for ($i=0; $i<count($addons_data); $i++) {
@@ -1137,17 +1137,17 @@ class SharingApiController extends AppController
'users' => $addon['User'],
'eula' => $addon['Translation']['eula']['string'],
'averagerating' => $addon['Addon']['averagerating'],
- 'tags' => array(),
+ 'categories' => array(),
'compatible_apps' => array(),
'all_compatible_os' => array(),
'fileinfo' => array()
);
- // Add the list of tags into the addon details
- foreach ($addon['Tag'] as $x) {
- $x = $all_tags[ $x['id'] ];
- $addon_out['tags'][] = array(
- 'id' => $x['Tag']['id'],
+ // Add the list of categories into the addon details
+ foreach ($addon['Category'] as $x) {
+ $x = $all_categories[ $x['id'] ];
+ $addon_out['categories'][] = array(
+ 'id' => $x['Category']['id'],
'name' => $x['Translation']['name']['string']
);
}
diff --git a/site/app/controllers/tags_controller.php b/site/app/controllers/tags_controller.php
new file mode 100644
index 0000000..a656b4e
--- /dev/null
+++ b/site/app/controllers/tags_controller.php
@@ -0,0 +1,298 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Les Orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class TagsController extends AppController
+{
+ var $name = 'Tags';
+ var $layout = 'mozilla';
+ var $uses = array('Addon', 'Eventlog', 'Review', 'Tag', 'Translation', 'Version', 'ReviewsModerationFlag', 'UserTagAddon');
+ var $components = array('Amo', 'Pagination', 'Session');
+ var $helpers = array('Html', 'Link', 'Localization', 'Pagination', 'Time');
+ var $namedArgs = true;
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox');
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ /**
+ * Add a new tag (AJAX)
+ **/
+
+ function add_ajax($addon_id, $tags_text) {
+ $this->_add_tag($addon_id, $tags_text);
+ $this->render('tag_added', 'ajax');
+ }
+
+ /**
+ * Add a new tag (Non-AJAX)
+ **/
+
+ function add() {
+ $addon_id = $_REQUEST['addonid'];
+ $tags_text = $_REQUEST['newTag'];
+ $this->_add_tag($addon_id, $tags_text);
+ // Send user back where he came from
+ if ($_REQUEST['origin'] == 'developers') {
+ $this->redirect('/developers/addon/edit/' . $addon_id . '/tags');
+ exit();
+ }
+ $this->redirect('/addon/' . $addon_id);
+ }
+
+ /**
+ * Internal function to add a new tag
+ **/
+ function _add_tag($addon_id, $tags_text) {
+ global $valid_status;
+
+ $this->Amo->clean($addon_id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+ $this->caching = false;
+
+ $user = $this->Session->read('User');
+
+ // Only 80 tags per addon.
+ $num_tags = count($this->Addon->getTagsByAddon($addon_id));
+
+ // Strip non-alphanumeric and quotes
+ // $tags_text = ereg_replace("[^A-Za-z0-9\"\']", "", $tags_text);
+ // Split based on whitespace, but keep quotes.
+ $split_tags = $this->splitTags($tags_text);
+ // Process each tag
+ foreach ($split_tags as $tag_text) {
+ // If we're up to 80 tags, then break
+ if ($num_tags > 79) {
+ $this->publish('message', 'Too many tags.');
+
+ break;
+ }
+
+ // Check if tag exists
+ $tag = $this->Tag->findByTagText($tag_text);
+ if (!empty($tag)) {
+ // Tag exists. Use this tag id.
+ $tag_id = $tag['Tag']['id'];
+ } else {
+ //Create Tag
+ $arrayTagData = array ('Tag'=>array(
+ 'tag_text' => $tag_text,
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ ));
+ $this->Tag->create(); // re-initialize the model
+ $this->Tag->save($arrayTagData);
+ $tag_id = $this->Tag->getLastInsertId();
+ unset($tag);
+ }
+
+ // Check if addon is already tagged with this tag
+ $existing = $this->UserTagAddon->find("tag_id = $tag_id and addon_id=$addon_id");
+ if (!empty($existing)) {
+ // Load the model to see who the owner is
+ //$addon = $this->Addon->getAddon($addon_id, array('User'));
+ $addon = $this->Addon->findById($addon_id);
+ foreach($addon['User'] as $addon_user) {
+ if ($addon_user['id'] == $user['id']) {
+ // Logged in user is tag owner.
+ $owner=true;
+ }
+ }
+ if (@$owner) {
+ // Replace tag.
+ $this->Addon->removeUserTagFromAddon($existing['UserTagAddon']['user_id'], $tag_id, $addon_id);
+ $this->Addon->addTag($addon_id, $tag_id, $user['id']);
+
+ } else {
+ // User is not owner; skip to next tag in list
+ continue;
+ }
+ } else {
+ // Add Tag to Addon
+ $this->Addon->addTag($addon_id, $tag_id, $user['id']);
+ $this->publish('message', 'Tag Added.');
+ }
+ $num_tags++;
+ } // foreach $tag
+
+
+ // Get tag list for addon
+ $addon_data = $this->Addon->findById($addon_id);
+ $tags = $this->Tag->makeTagList($addon_data, $user);
+ $this->publish('addon_id', $addon_data['Addon']['id']);
+ $this->publish('userTags', $tags['userTags']);
+ $this->publish('developerTags', $tags['developerTags']);
+ }
+
+ function addAndBlacklist() {
+ $tags_text = $_REQUEST['newTag'];
+ $split_tags = $this->splitTags($tags_text);
+ // Process each tag
+ foreach ($split_tags as $tag_text) {
+ // Check if tag exists
+ $tag = $this->Tag->findByTagText($tag_text);
+ if (!empty($tag)) {
+ // Tag exists. Use this tag id.
+ $tag_id = $tag['Tag']['id'];
+ } else {
+ //Create Tag
+ $arrayTagData = array ('Tag'=>array(
+ 'tag_text' => $tag_text,
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ ));
+ $this->Tag->create(); // re-initialize the model
+ $this->Tag->save($arrayTagData);
+ $tag_id = $this->Tag->getLastInsertId();
+
+ }
+ $this->Tag->blacklistTag($tag_id);
+ unset($tag);
+ }
+ $this->redirect('admin/tags');
+ }
+
+
+
+ function remove_ajax($addon_id, $tag_id) {
+ global $valid_status;
+
+ $this->Amo->clean($addon_id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+ $this->Addon->caching = false;
+
+ $user = $this->Session->read('User');
+ $this->Addon->removeTagFromAddons($tag_id, $addon_id);
+ // Get tag list for addon
+
+ $addon_data = $this->Addon->findById($addon_id);
+ $tags = $this->Tag->makeTagList($addon_data, $user);
+ $this->publish('addon_id', $addon_data['Addon']['id']);
+ $this->publish('userTags', $tags['userTags']);
+ $this->publish('developerTags', $tags['developerTags']);
+ $this->publish('message', 'Tag Removed.');
+
+ $this->render('tag_added', 'ajax');
+
+ }
+
+ function remove($addon_id, $tag_id, $origin) {
+ global $valid_status;
+
+ $this->Amo->clean($addon_id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+ $this->Addon->caching = false;
+
+ $user = $this->Session->read('User');
+ $this->Addon->removeTagFromAddons($tag_id, $addon_id);
+ $this->flash('Tag removed');
+ if ($origin == 'developers') {
+ $this->redirect('/developers/addon/edit/' . $addon_id . '/tags');
+ exit();
+ }
+ $this->redirect('/addon/' . $addon_id);
+ }
+
+
+
+
+ function splitTags($string)
+ {
+ // Code from http://us2.php.net/manual/en/function.split.php#81490
+ $separator=' ';
+ $elements = explode($separator, $string);
+ for ($i = 0; $i < count($elements); $i++) {
+ $nquotes = substr_count($elements[$i], '"');
+ if ($nquotes %2 == 1) {
+ for ($j = $i+1; $j < count($elements); $j++) {
+ if (substr_count($elements[$j], '"') %2 == 1) { // Look for an odd-number of quotes
+ // Put the quoted string's pieces back together again
+ array_splice($elements, $i, $j-$i+1,
+ implode($separator, array_slice($elements, $i, $j-$i+1)));
+ break;
+ }
+ }
+ }
+ if ($nquotes > 0) {
+ // Remove first and last quotes, then merge pairs of quotes
+ $qstr =& $elements[$i];
+ $qstr = substr_replace($qstr, '', strpos($qstr, '"'), 1);
+ $qstr = substr_replace($qstr, '', strrpos($qstr, '"'), 1);
+ $qstr = str_replace('""', '"', $qstr);
+ }
+ }
+ return $elements;
+ return $elements;
+ }
+
+
+
+ function lookup() {
+ global $valid_status;
+ $text = $_REQUEST['q'];
+
+ $this->Amo->clean($id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+ $tags = $this->Tag->findAll("Tag.tag_text like '$text%' and blacklisted=0");
+ $this->publish('tags',$tags);
+ $this->render('ajax/tag_lookup', 'ajax');
+
+ }
+
+
+
+ function top($numTags=100, $sortBy="freq") {
+ // get the top tags
+ $this->publish('numTags', $numTags);
+
+ $topTags = $this->Tag->getTop($numTags, $sortBy);
+ $this->publish('topTags', $topTags);
+ }
+ }
+
+
+
+?>
diff --git a/site/app/controllers/tests_controller.php b/site/app/controllers/tests_controller.php
index 05893ca..c042476 100644
--- a/site/app/controllers/tests_controller.php
+++ b/site/app/controllers/tests_controller.php
@@ -63,7 +63,7 @@ function actionPath($action) {
class TestsController extends AppController {
var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Cannedresponse', 'Favorite', 'Feature', 'File',
- 'Platform', 'Preview', 'Review', 'Reviewrating', 'Tag', 'Translation', 'User', 'Version');
+ 'Platform', 'Preview', 'Review', 'Reviewrating', 'Category', 'Translation', 'User', 'Version');
var $helpers = array('Html', 'Ajax', 'Javascript');
var $aclExceptions = array('bot');
// Disable permissions if we're in a DEV sandbox.
diff --git a/site/app/locale/af/LC_MESSAGES/messages.po b/site/app/locale/af/LC_MESSAGES/messages.po
index c08f9b4..2d7118f 100644
--- a/site/app/locale/af/LC_MESSAGES/messages.po
+++ b/site/app/locale/af/LC_MESSAGES/messages.po
@@ -1581,7 +1581,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1589,14 +1589,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ar/LC_MESSAGES/messages.po b/site/app/locale/ar/LC_MESSAGES/messages.po
index f5386e6..4da428b 100644
--- a/site/app/locale/ar/LC_MESSAGES/messages.po
+++ b/site/app/locale/ar/LC_MESSAGES/messages.po
@@ -1437,7 +1437,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1445,14 +1445,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
@@ -1480,7 +1480,7 @@ msgstr "%1$s updated platform translations for %2$s"
#. %2$s is a locale, like en-US.
#: controllers/components/audit.php:270
#, fuzzy
-msgid "audit_update_tags"
+msgid "audit_update_categories"
msgstr "%1$s updated category translations for %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ca/LC_MESSAGES/messages.po b/site/app/locale/ca/LC_MESSAGES/messages.po
index 22cc08e..d24126c 100644
--- a/site/app/locale/ca/LC_MESSAGES/messages.po
+++ b/site/app/locale/ca/LC_MESSAGES/messages.po
@@ -1378,20 +1378,20 @@ msgstr "En/na %1$s va validar l'acció de seguretat desconeguda %2$s amb id %3$s
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "En/na %1$s va crear la categoria %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "En/na %1$s va suprimir la categoria %2$s (id %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "En/na %1$s va editar la categoria %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/cs/LC_MESSAGES/messages.po b/site/app/locale/cs/LC_MESSAGES/messages.po
index 3baa103..08c7e79 100644
--- a/site/app/locale/cs/LC_MESSAGES/messages.po
+++ b/site/app/locale/cs/LC_MESSAGES/messages.po
@@ -1372,20 +1372,20 @@ msgstr "Uživatel %1$s provedl neznámou bezpeÄnostní akci %2$s na ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "Uživatel %1$s vytvořil štítek %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "Uživatel %1$s odstranil kategorii %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "Uživatel %1$s upravil kategorii %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/cy/LC_MESSAGES/messages.po b/site/app/locale/cy/LC_MESSAGES/messages.po
index ee8e74d..9ae3bff 100644
--- a/site/app/locale/cy/LC_MESSAGES/messages.po
+++ b/site/app/locale/cy/LC_MESSAGES/messages.po
@@ -1482,7 +1482,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1490,14 +1490,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/da/LC_MESSAGES/messages.po b/site/app/locale/da/LC_MESSAGES/messages.po
index 93d1638..2c76698 100644
--- a/site/app/locale/da/LC_MESSAGES/messages.po
+++ b/site/app/locale/da/LC_MESSAGES/messages.po
@@ -1391,20 +1391,20 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/de/LC_MESSAGES/messages.po b/site/app/locale/de/LC_MESSAGES/messages.po
index a922808..6da20c1 100644
--- a/site/app/locale/de/LC_MESSAGES/messages.po
+++ b/site/app/locale/de/LC_MESSAGES/messages.po
@@ -1374,20 +1374,20 @@ msgstr "%1$s führte unbekannte Sicherheits-Aktion %2$s auf ID %3$s aus"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s fügte Kategorie %2$s hinzu"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s löschte Kategorie %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s editierte Kategorie %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/el/LC_MESSAGES/messages.po b/site/app/locale/el/LC_MESSAGES/messages.po
index 50a6053..b684677 100644
--- a/site/app/locale/el/LC_MESSAGES/messages.po
+++ b/site/app/locale/el/LC_MESSAGES/messages.po
@@ -1437,20 +1437,20 @@ msgstr "Ο/Η %1$s υπέβαλε την άγνωστη ενέÏγεια ασφÎ
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "Ο/Η %1$s δημιοÏÏγησε την ετικέτα %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "Ο/Η %1$s διέγÏαψε την κατηγοÏίαy %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "Ο/Η %1$s επεξεÏγάστηκε την κατηγοÏία %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/en_US/LC_MESSAGES/messages.po b/site/app/locale/en_US/LC_MESSAGES/messages.po
index b75dc7b..75a1993 100644
--- a/site/app/locale/en_US/LC_MESSAGES/messages.po
+++ b/site/app/locale/en_US/LC_MESSAGES/messages.po
@@ -1355,20 +1355,20 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
@@ -2928,6 +2928,11 @@ msgid "devcp_edit_dd_manage_categories"
msgstr ""
"Select the relevant categories for each application your add-on supports."
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_tags"
+msgstr ""
+"Add tags to your add-on."
+
#: views/developers/addon_edit.thtml:51
msgid "devcp_edit_dd_manage_description"
msgstr ""
@@ -3014,6 +3019,10 @@ msgstr "Manage Add-on Authors"
msgid "devcp_edit_dt_manage_categories"
msgstr "Manage Add-on Categories"
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dt_manage_tags"
+msgstr "Manage Add-on Tags"
+
#: views/developers/addon_edit.thtml:50
msgid "devcp_edit_dt_manage_descriptions"
msgstr "Manage Add-on Descriptions"
diff --git a/site/app/locale/es_ES/LC_MESSAGES/messages.po b/site/app/locale/es_ES/LC_MESSAGES/messages.po
index deca9b7..3f0a96c 100644
--- a/site/app/locale/es_ES/LC_MESSAGES/messages.po
+++ b/site/app/locale/es_ES/LC_MESSAGES/messages.po
@@ -1418,20 +1418,20 @@ msgstr "%1$s ha realizado una acción de seguridad desconocida %2$s al ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s ha creado la etiqueta %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s ha borrado la categoría %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s ha editado la categoría %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/eu/LC_MESSAGES/messages.po b/site/app/locale/eu/LC_MESSAGES/messages.po
index 4026e76..51536c1 100644
--- a/site/app/locale/eu/LC_MESSAGES/messages.po
+++ b/site/app/locale/eu/LC_MESSAGES/messages.po
@@ -1508,7 +1508,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1516,14 +1516,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/fa/LC_MESSAGES/messages.po b/site/app/locale/fa/LC_MESSAGES/messages.po
index 8c28794..cd5bb40 100644
--- a/site/app/locale/fa/LC_MESSAGES/messages.po
+++ b/site/app/locale/fa/LC_MESSAGES/messages.po
@@ -1442,7 +1442,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1450,14 +1450,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/fi/LC_MESSAGES/messages.po b/site/app/locale/fi/LC_MESSAGES/messages.po
index 2d28904..e0f795b 100644
--- a/site/app/locale/fi/LC_MESSAGES/messages.po
+++ b/site/app/locale/fi/LC_MESSAGES/messages.po
@@ -1522,7 +1522,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1530,14 +1530,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/fr/LC_MESSAGES/messages.po b/site/app/locale/fr/LC_MESSAGES/messages.po
index 7e6eb0f..735abfd 100644
--- a/site/app/locale/fr/LC_MESSAGES/messages.po
+++ b/site/app/locale/fr/LC_MESSAGES/messages.po
@@ -1449,7 +1449,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1457,14 +1457,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/fy_NL/LC_MESSAGES/messages.po b/site/app/locale/fy_NL/LC_MESSAGES/messages.po
index 4677c23..8c865a9 100644
--- a/site/app/locale/fy_NL/LC_MESSAGES/messages.po
+++ b/site/app/locale/fy_NL/LC_MESSAGES/messages.po
@@ -1610,7 +1610,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1618,14 +1618,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ga_IE/LC_MESSAGES/messages.po b/site/app/locale/ga_IE/LC_MESSAGES/messages.po
index 77272e0..b4103a4 100644
--- a/site/app/locale/ga_IE/LC_MESSAGES/messages.po
+++ b/site/app/locale/ga_IE/LC_MESSAGES/messages.po
@@ -1477,7 +1477,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1485,14 +1485,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/he/LC_MESSAGES/messages.po b/site/app/locale/he/LC_MESSAGES/messages.po
index dd41c6a..9d33e10 100644
--- a/site/app/locale/he/LC_MESSAGES/messages.po
+++ b/site/app/locale/he/LC_MESSAGES/messages.po
@@ -1452,7 +1452,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1460,14 +1460,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/hu/LC_MESSAGES/messages.po b/site/app/locale/hu/LC_MESSAGES/messages.po
index 20ea1d7..6085a28 100644
--- a/site/app/locale/hu/LC_MESSAGES/messages.po
+++ b/site/app/locale/hu/LC_MESSAGES/messages.po
@@ -1472,7 +1472,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1480,14 +1480,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/id/LC_MESSAGES/messages.po b/site/app/locale/id/LC_MESSAGES/messages.po
index 3455fd7..8257471 100644
--- a/site/app/locale/id/LC_MESSAGES/messages.po
+++ b/site/app/locale/id/LC_MESSAGES/messages.po
@@ -1446,7 +1446,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1454,14 +1454,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/it/LC_MESSAGES/messages.po b/site/app/locale/it/LC_MESSAGES/messages.po
index cc9bf9e..2988bde 100644
--- a/site/app/locale/it/LC_MESSAGES/messages.po
+++ b/site/app/locale/it/LC_MESSAGES/messages.po
@@ -1412,20 +1412,20 @@ msgstr "%1$s ha eseguito un'azione di sicurezza sconosciuta %2$s sull'elemento c
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s ha creato l'etichetta %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s ha eliminato la categoria %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s ha modificato la categoria %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ja/LC_MESSAGES/messages.po b/site/app/locale/ja/LC_MESSAGES/messages.po
index fac9ed0..81178bc 100644
--- a/site/app/locale/ja/LC_MESSAGES/messages.po
+++ b/site/app/locale/ja/LC_MESSAGES/messages.po
@@ -1368,20 +1368,20 @@ msgstr "%1$s ãŒä¸æ˜Žãªã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ %2$s ã‚’ ID %3$s ã¸ã
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s ãŒã‚¿ã‚° %2$s を作æˆã—ã¾ã—ãŸ"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s ãŒã‚«ãƒ†ã‚´ãƒª %2$s (ID %3$s) を削除ã—ã¾ã—ãŸ"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s ãŒã‚«ãƒ†ã‚´ãƒª %2$s を編集ã—ã¾ã—ãŸ"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ko/LC_MESSAGES/messages.po b/site/app/locale/ko/LC_MESSAGES/messages.po
index 92871bb..c1eae64 100644
--- a/site/app/locale/ko/LC_MESSAGES/messages.po
+++ b/site/app/locale/ko/LC_MESSAGES/messages.po
@@ -1296,7 +1296,7 @@ msgstr "%1$së‹˜ì´ ID %3$sì— ëŒ€í•œ ì•Œ 수 없는 보안 í–‰ë™ %2$sì— ì—°ë£¨
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$së‹˜ì´ %2$s 태그 ìƒì„±"
# ì›ë¬¸: %1$s deleted category %2$s (ID %3$s)
@@ -1304,14 +1304,14 @@ msgstr "%1$së‹˜ì´ %2$s 태그 ìƒì„±"
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$së‹˜ì´ %2$s 분류 ì‚­ì œ (ID %3$s)"
# ì›ë¬¸: %1$s edited category %2$s
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$së‹˜ì´ %2$s 분류 편집"
# ì›ë¬¸: %1$s updated application translations for %2$s
diff --git a/site/app/locale/mn/LC_MESSAGES/messages.po b/site/app/locale/mn/LC_MESSAGES/messages.po
index a93a4e3..1f83a9c 100644
--- a/site/app/locale/mn/LC_MESSAGES/messages.po
+++ b/site/app/locale/mn/LC_MESSAGES/messages.po
@@ -1480,7 +1480,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1488,14 +1488,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/nl/LC_MESSAGES/messages.po b/site/app/locale/nl/LC_MESSAGES/messages.po
index 46698ba..6a2dc0a 100644
--- a/site/app/locale/nl/LC_MESSAGES/messages.po
+++ b/site/app/locale/nl/LC_MESSAGES/messages.po
@@ -1370,20 +1370,20 @@ msgstr "%1$s heeft een onbekende beveiligingsactie %2$s uitgevoerd op ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s heeft label %2$s aangemaakt"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s heeft categorie %2$s (ID %3$s) verwijderd"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s heeft categorie %2$s bewerkt"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/pl/LC_MESSAGES/messages.po b/site/app/locale/pl/LC_MESSAGES/messages.po
index c399527..40d347d 100644
--- a/site/app/locale/pl/LC_MESSAGES/messages.po
+++ b/site/app/locale/pl/LC_MESSAGES/messages.po
@@ -1425,20 +1425,20 @@ msgstr "%1$s przypisał nieznaną czynność z zakresu bezpieczeństwa %2$s do I
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s utworzył etykietę %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s usunÄ…Å‚ kategoriÄ™ %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edytował kategorię %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/pt_BR/LC_MESSAGES/messages.po b/site/app/locale/pt_BR/LC_MESSAGES/messages.po
index f44ef8b..4163d05 100644
--- a/site/app/locale/pt_BR/LC_MESSAGES/messages.po
+++ b/site/app/locale/pt_BR/LC_MESSAGES/messages.po
@@ -1418,20 +1418,20 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/pt_PT/LC_MESSAGES/messages.po b/site/app/locale/pt_PT/LC_MESSAGES/messages.po
index c0784be..b95292d 100644
--- a/site/app/locale/pt_PT/LC_MESSAGES/messages.po
+++ b/site/app/locale/pt_PT/LC_MESSAGES/messages.po
@@ -1409,20 +1409,20 @@ msgstr "%1$s committed acção de segurança desconhecido %2$s para o ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s criou a etiqueta %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s eliminou a categoria %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s editou a categoria %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ro/LC_MESSAGES/messages.po b/site/app/locale/ro/LC_MESSAGES/messages.po
index 2306e45..dde55f8 100644
--- a/site/app/locale/ro/LC_MESSAGES/messages.po
+++ b/site/app/locale/ro/LC_MESSAGES/messages.po
@@ -1389,20 +1389,20 @@ msgstr ""
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr ""
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr ""
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr ""
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/ru/LC_MESSAGES/messages.po b/site/app/locale/ru/LC_MESSAGES/messages.po
index f6ccaf1..9452f9f 100644
--- a/site/app/locale/ru/LC_MESSAGES/messages.po
+++ b/site/app/locale/ru/LC_MESSAGES/messages.po
@@ -1405,20 +1405,20 @@ msgstr ""
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s Ñоздал метку %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s удалил категорию %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s отредактировал категорию %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/sk/LC_MESSAGES/messages.po b/site/app/locale/sk/LC_MESSAGES/messages.po
index 865d829..6e7c4f8 100644
--- a/site/app/locale/sk/LC_MESSAGES/messages.po
+++ b/site/app/locale/sk/LC_MESSAGES/messages.po
@@ -1447,20 +1447,20 @@ msgstr "Používateľ %1$s vykonal neznámu akciu zabezpeÄenia '%2$s' pre ID %3
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "Používateľ %1$s vytvoril kategóriu %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "Používateľ %1$s odstránil kategóriu %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "Používateľ %1$s upravil kategóriu %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/sq/LC_MESSAGES/messages.po b/site/app/locale/sq/LC_MESSAGES/messages.po
index 168612f..4ef89d5 100644
--- a/site/app/locale/sq/LC_MESSAGES/messages.po
+++ b/site/app/locale/sq/LC_MESSAGES/messages.po
@@ -1407,20 +1407,20 @@ msgstr "%1$s kreu një veprim të panjohur sigurien %2$s mbi ID %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s krijoi etiketën %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s fshiu kategorinë %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s përpunoi kategorinë %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/sv_SE/LC_MESSAGES/messages.po b/site/app/locale/sv_SE/LC_MESSAGES/messages.po
index b4d8372..029015f 100644
--- a/site/app/locale/sv_SE/LC_MESSAGES/messages.po
+++ b/site/app/locale/sv_SE/LC_MESSAGES/messages.po
@@ -1360,20 +1360,20 @@ msgstr "%1$s utförde okänd säkerhetshandling %2$s på id %3$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s skapade etiketten %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s tog bort kategorin %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s redigerade kategorin %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/tr/LC_MESSAGES/messages.po b/site/app/locale/tr/LC_MESSAGES/messages.po
index 469e2a6..013ac41 100644
--- a/site/app/locale/tr/LC_MESSAGES/messages.po
+++ b/site/app/locale/tr/LC_MESSAGES/messages.po
@@ -1583,7 +1583,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1591,14 +1591,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/uk/LC_MESSAGES/messages.po b/site/app/locale/uk/LC_MESSAGES/messages.po
index c7e8b3f..22de164 100644
--- a/site/app/locale/uk/LC_MESSAGES/messages.po
+++ b/site/app/locale/uk/LC_MESSAGES/messages.po
@@ -1443,7 +1443,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1451,14 +1451,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/vi/LC_MESSAGES/messages.po b/site/app/locale/vi/LC_MESSAGES/messages.po
index cad1712..8684483 100644
--- a/site/app/locale/vi/LC_MESSAGES/messages.po
+++ b/site/app/locale/vi/LC_MESSAGES/messages.po
@@ -1408,20 +1408,20 @@ msgstr "%1$s thực hiện thao tác bảo mật chưa biết %2$s để ID %3$s
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s đã tạo nhãn %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s đã xóa phân mục %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s đã chỉnh sửa phân mục %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/zh_CN/LC_MESSAGES/messages.po b/site/app/locale/zh_CN/LC_MESSAGES/messages.po
index 02aadfe..de2d4d3 100644
--- a/site/app/locale/zh_CN/LC_MESSAGES/messages.po
+++ b/site/app/locale/zh_CN/LC_MESSAGES/messages.po
@@ -1460,7 +1460,7 @@ msgstr "%1$s committed unknown security action %2$s to ID %3$s"
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
#, fuzzy
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s created tag %2$s"
#. %1$s is <a>user name</a>
@@ -1468,14 +1468,14 @@ msgstr "%1$s created tag %2$s"
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
#, fuzzy
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s deleted category %2$s (ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
#, fuzzy
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s edited category %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/locale/zh_TW/LC_MESSAGES/messages.po b/site/app/locale/zh_TW/LC_MESSAGES/messages.po
index e608a35..ea4b6b1 100644
--- a/site/app/locale/zh_TW/LC_MESSAGES/messages.po
+++ b/site/app/locale/zh_TW/LC_MESSAGES/messages.po
@@ -1321,20 +1321,20 @@ msgstr "%1$s å° ID %3$s æ交了未知的安全性行動 %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:118
-msgid "audit_tag_create"
+msgid "audit_category_create"
msgstr "%1$s 新增了分類 %2$s"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#. %3$s is a numeric id.
#: controllers/components/audit.php:126
-msgid "audit_tag_delete"
+msgid "audit_category_delete"
msgstr "%1$s 刪除了分類 %2$s(ID %3$s)"
#. %1$s is <a>user name</a>
#. %2$s is a category name, like <a>Search Tools</a>
#: controllers/components/audit.php:121
-msgid "audit_tag_edit"
+msgid "audit_category_edit"
msgstr "%1$s 編輯了分類 %2$s"
#. %1$s is <a>user name</a>
diff --git a/site/app/models/addon.php b/site/app/models/addon.php
index 2ee1f01..5b53de2 100644
--- a/site/app/models/addon.php
+++ b/site/app/models/addon.php
@@ -50,17 +50,24 @@ class Addon extends AppModel
'conditions' => 'addons_users.listed=1',
'order' => 'addons_users.position'
),
- 'Tag' =>
- array('className' => 'Tag',
- 'joinTable' => 'addons_tags',
+ 'Category' =>
+ array('className' => 'Category',
+ 'joinTable' => 'addons_categories',
'foreignKey' => 'addon_id',
- 'associationForeignKey'=> 'tag_id'
+ 'associationForeignKey'=> 'category_id'
),
'Collection' =>
array('classname' => 'Collection',
'joinTable' => 'addons_collections',
'foreignKey' => 'addon_id',
- 'associationForeignKey' => 'collection_id')
+ 'associationForeignKey' => 'collection_id'),
+
+ 'Tag' =>
+ array('className' => 'Tag',
+ 'joinTable' => 'users_tags_addons',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey' => 'tag_id'
+ )
);
var $belongsTo = array('Addontype');
var $hasMany = array('Version' =>
@@ -74,8 +81,8 @@ class Addon extends AppModel
'finderSql' => ''
),
// see the addon_tag model for details
- 'AddonTag' =>
- array('classname' => 'AddonTag',
+ 'AddonCategory' =>
+ array('classname' => 'AddonCategory',
'conditions' => '',
'order' => '',
'limit' => '',
@@ -103,6 +110,10 @@ class Addon extends AppModel
'dependent' => true,
'exclusive' => false,
'finderSql' => ''
+ ),
+ 'UserTagAddon' =>
+ array('className' => 'UserTagAddon'
+
)
);
@@ -181,11 +192,11 @@ class Addon extends AppModel
foreach ($associations as $association) {
switch ($association) {
- case 'all_tags':
+ case 'all_categories':
// all categories this add-on is associated with
$this->bindModel(array('hasMany' =>
- array('AddonTag' =>
- array('className' => 'AddonTag',
+ array('AddonCategory' =>
+ array('className' => 'AddonCategory',
'foreignKey' => 'addon_id'
))));
break;
@@ -224,16 +235,16 @@ class Addon extends AppModel
'weeklydownloads', 'addontype_id', 'averagerating', 'totalreviews'));
break;
- case 'single_tag':
+ case 'single_category':
// the first category this add-on is associated with
$this->bindModel(array('hasMany' =>
- array('AddonTag' =>
- array('className' => 'AddonTag',
+ array('AddonCategory' =>
+ array('className' => 'AddonCategory',
'foreignKey' => 'addon_id',
'limit' => 1
))));
break;
-
+
default:
debug("Association $association not declared!");
break;
@@ -291,17 +302,17 @@ class Addon extends AppModel
}
}
- // add addon tags
- if ((in_array('all_tags', $associations) || in_array('single_tag', $associations))
- && !empty($addon['AddonTag'])) {
-
- $_tag_ids = array();
- foreach ($addon['AddonTag'] as $_tag)
- $_tag_ids[] = $_tag['tag_id'];
- $tags = array();
- if (!empty($_tag_ids))
- $tags = $this->Tag->findAll(array('Tag.id' => $_tag_ids, 'Tag.application_id' => APP_ID));
- $addon['Tag'] = $tags;
+ // add addon categories
+ if ((in_array('all_categories', $associations) || in_array('single_category', $associations))
+ && !empty($addon['AddonCategory'])) {
+
+ $_category_ids = array();
+ foreach ($addon['AddonCategory'] as $_category)
+ $_category_ids[] = $_category['category_id'];
+ $categories = array();
+ if (!empty($_category_ids))
+ $categories = $this->Category->findAll(array('Category.id' => $_category_ids, 'Category.application_id' => APP_ID));
+ $addon['Category'] = $categories;
}
// cache this object...
@@ -350,7 +361,7 @@ class Addon extends AppModel
$add_joins = $orderby = $limitclause = $groupby = $where = '';
if ($category != 'all') {
// if cat == all, don't worry about the category. Otherwise only select the chosen one.
- $add_joins .= "INNER JOIN addons_tags AS at ON (at.tag_id = '{$category}' AND at.addon_id = Addon.id) ";
+ $add_joins .= "INNER JOIN addons_categories AS at ON (at.category_id = '{$category}' AND at.addon_id = Addon.id) ";
}
// only select add-ons that have any files to offer
$add_joins .= "INNER JOIN files AS File ON (Version.id = File.version_id AND File.status IN (".implode(',',$status).")) ";
@@ -561,23 +572,23 @@ class Addon extends AppModel
$addontypes = array($addontypes);
// Construct the SQL query, stolen from getAddonsByCategory
- $sql = 'SELECT at.tag_id, COUNT(DISTINCT Addon.id) AS co '
+ $sql = 'SELECT at.category_id, COUNT(DISTINCT Addon.id) AS co '
.'FROM addons AS Addon '
.'INNER JOIN versions AS Version ON (Addon.id = Version.addon_id) '
.'INNER JOIN applications_versions AS av ON (av.version_id = Version.id AND av.application_id = '.APP_ID.') '
- .'INNER JOIN addons_tags AS at ON (at.addon_id = Addon.id) '
+ .'INNER JOIN addons_categories AS at ON (at.addon_id = Addon.id) '
.'INNER JOIN files AS File ON (Version.id = File.version_id AND File.status IN ('.implode(',',$status).')) '
.'WHERE Addon.addontype_id IN('.implode(',',$addontypes).') '
.'AND Addon.status IN('.implode(',',$status).') '
.'AND Addon.inactive = 0 '
- .'GROUP BY at.tag_id';
+ .'GROUP BY at.category_id';
$rows = $this->query($sql, true);
// Reduce the rows from the DB down to simple ID / count
$addon_counts = array();
foreach ($rows as $row) {
- $addon_counts[ $row['at']['tag_id'] ] = $row[0]['co'];
+ $addon_counts[ $row['at']['category_id'] ] = $row[0]['co'];
}
return $addon_counts;
@@ -761,7 +772,7 @@ class Addon extends AppModel
$addontypes = ADDON_EXTENSION, $category = 'all', $sort_by = 'name',
$direction = 'ASC', $limit = '5', $page = '1', $friends = '', $includeFiles = false) {
- $associations = array('all_tags', 'authors', 'compatible_apps',
+ $associations = array('all_categories', 'authors', 'compatible_apps',
'latest_version', 'list_details');
if ($includeFiles) {
$associations[] = 'files';
@@ -777,5 +788,89 @@ class Addon extends AppModel
return $this->countAddonsInCategory($status, $addontypes, $category, $friends);
}
}
+
+ /**
+ * adds a tag to an addon
+ * -using saveAuthor() as an example
+ * -trigger trg_tag_stat_inc will update tag_stat
+ */
+ function addTag($addonId, $tagId, $userId) {
+ $sql = "INSERT IGNORE INTO users_tags_addons set user_id = {$userId}, tag_id = {$tagId}, addon_id = {$addonId}, created = now()";
+ $ret = $this->execute($sql);
+ }
+
+ /**
+ * -trigger trg_tag_stat_dec will update tag_stat
+ */
+ function removeUserTagFromAddon($user_id, $tag_id, $addon_id) {
+ $this->caching = false;
+
+ $this->execute("DELETE FROM users_tags_addons where user_id={$user_id} AND tag_id={$tag_id} AND addon_id = {$addon_id}");
+ $this->caching = true;
+
+ }
+
+ /**
+ * -trigger trg_tag_stat_dec will update tag_stat
+ */
+ function removeTagFromAddons($tag_id, $addon_id) {
+ $this->execute("DELETE FROM users_tags_addons where tag_id={$tag_id} AND addon_id = {$addon_id}");
+ }
+
+ /**
+ * Gets all the tags for this addon
+ */
+ function getTagsByAddon($addon_id) {
+ $userTagAddons = $this->UserTagAddon->findAll(array('addon_id' => $addon_id));
+ $tagIds = array();
+ foreach ($userTagAddons as $uta) {
+ $tagIds[] = $uta['UserTagAddon']['tag_id'];
+ }
+
+ return $this->Tag->findAllById($tagIds,null,"Tag.tag_text asc");
+ }
+
+ function getTagsByUserTagAddon($users_tags_addons) {
+ $tagIds = array();
+ foreach ($users_tags_addons as $uta) {
+ $tagIds[] = $uta['UserTagAddon']['tag_id'];
+ }
+
+ if( count($tagIds) > 0)
+ return $this->Tag->findAllById($tagIds);
+ else {
+ return array();
+ }
+
+ }
+
+ function getAddonsByUserTagAddon($users_tags_addons) {
+ $addonIds = array();
+ foreach ($users_tags_addons as $uta) {
+ $addonIds[] = $uta['UserTagAddon']['addon_id'];
+ }
+
+ if( count($addonIds) > 0)
+ return $this->findAllById($addonIds);
+ else {
+ return array();
+ }
+
+ }
+
+ function getTagsByUser($user_id) {
+ $userTagAddons = $this->UserTagAddon->findAll(array('user_id' => $user_id));
+ //print_r($userTagAddons);
+ return $this->getTagsByUserTagAddon($userTagAddons);
+ }
+
+
+ function getAddonsByTag($tag_id) {
+ $userTagAddons = $this->UserTagAddon->findAll(array('tag_id' => $tag_id));
+ return $this->getAddonsByUserTagAddon($userTagAddons);
+ }
+
+
+
}
?>
diff --git a/site/app/models/addon_tag.php b/site/app/models/addon_category.php
index 19cbe2e..2d4a96f 100644
--- a/site/app/models/addon_tag.php
+++ b/site/app/models/addon_category.php
@@ -37,42 +37,42 @@
*
* ***** END LICENSE BLOCK ***** */
-class AddonTag extends AppModel
+class AddonCategory extends AppModel
{
// This is sort of experimental. I need to retrieve information stored with this
- // relationship (in the addons_tags model). Cake 1.1 doesn't provide a way to do that
+ // relationship (in the addons_categories model). Cake 1.1 doesn't provide a way to do that
// so I'm sort of abusing it here and making the Addon model do an extra hasMany join
- // against this model (it's already doing an HABTM join against Tag using this table).
+ // against this model (it's already doing an HABTM join against Category using this table).
// Cake 1.2 fixes this problem and we can rip all this code out... --clouserw
- var $name = 'AddonTag';
- var $useTable = 'addons_tags';
- var $belongsTo = array('Addon', 'Tag');
+ var $name = 'AddonCategory';
+ var $useTable = 'addons_categories';
+ var $belongsTo = array('Addon', 'Category');
var $recursive = -1;
/**
* Returns add-ons for the given category (recommended or not).
*
- * @param mixed single tag or array of tags
+ * @param mixed single category or array of categories
* @param bool return recommended or non-recommended add-ons?
* @param int limit amount of add-ons to return
* @param string SQL order, default random
* @return array Add-on IDs that match the criteria
*/
- function getRandomAddons($tag, $recommended=false, $limit=null, $order='RAND()', $addontype=null) {
+ function getRandomAddons($category, $recommended=false, $limit=null, $order='RAND()', $addontype=null) {
global $valid_status;
- if (!is_array($tag)) $tag = array($tag);
+ if (!is_array($category)) $category = array($category);
if (!is_null($addontype) && !is_array($addontype)) $addontype = array($addontype);
$raw_addons = $this->query(
"SELECT DISTINCT Addon.id "
- ."FROM addons_tags AS AddonTag "
- ."INNER JOIN addons AS Addon ON (AddonTag.addon_id = Addon.id)"
+ ."FROM addons_categories AS AddonCategory "
+ ."INNER JOIN addons AS Addon ON (AddonCategory.addon_id = Addon.id)"
."WHERE "
- ."AddonTag.tag_id IN (".implode(',', $tag).') AND '
- ."AddonTag.feature = ".($recommended ? '1' : '0')." AND "
+ ."AddonCategory.category_id IN (".implode(',', $category).') AND '
+ ."AddonCategory.feature = ".($recommended ? '1' : '0')." AND "
."Addon.status IN (".implode(',', $valid_status).') AND '
.'Addon.inactive = 0 '
.(!empty($addontype) ? ' AND Addon.addontype_id IN ('.implode(',', $addontype).') ' : '')
diff --git a/site/app/models/addontype.php b/site/app/models/addontype.php
index 8353724..af50036 100644
--- a/site/app/models/addontype.php
+++ b/site/app/models/addontype.php
@@ -51,8 +51,8 @@ class Addontype extends AppModel
'exclusive' => false,
'finderSql' => ''
),
- 'Tag' =>
- array('className' => 'Tag',
+ 'Category' =>
+ array('className' => 'Category',
'conditions' => '',
'order' => '',
'limit' => '',
diff --git a/site/app/models/application.php b/site/app/models/application.php
index da37fb2..4845830 100644
--- a/site/app/models/application.php
+++ b/site/app/models/application.php
@@ -50,8 +50,8 @@ class Application extends AppModel
'exclusive' => false,
'finderSql' => ''
),
- 'Tag' =>
- array('className' => 'Tag',
+ 'Category' =>
+ array('className' => 'Category',
'conditions' => '',
'order' => '',
'limit' => '',
diff --git a/site/app/models/category.php b/site/app/models/category.php
new file mode 100644
index 0000000..6d9f64e
--- /dev/null
+++ b/site/app/models/category.php
@@ -0,0 +1,134 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Category extends AppModel
+{
+ var $name = 'Category';
+ var $hasAndBelongsToMany_full = array('Addon' =>
+ array('className' => 'Addon',
+ 'joinTable' => 'addons_categories',
+ 'foreignKey' => 'category_id',
+ 'associationForeignKey'=> 'addon_id')
+ );
+ var $belongsTo = array('Addontype', 'Application');
+
+ /**
+ * Fields here will looked up in the translations table
+ *
+ * @var array
+ * @access public
+ */
+ var $translated_fields = array('name', 'description');
+
+ /**
+ * Saves selected categories by only removing deleted categories and inserting
+ * new categories rather than deleting all existing categories and adding all
+ * back.
+ * @param int $addon_id add-on id
+ * @param array $data category data from form
+ */
+ function saveCategories($addon_id, $data) {
+ if (empty($data)) {
+ return;
+ }
+
+ foreach ($data as $application_id => $selectedCategories) {
+ foreach ($selectedCategories as $category_id) {
+ if (!empty($category_id)) {
+ $newCategories[] = $category_id;
+ }
+ }
+ }
+
+ if (!empty($newCategories)) {
+ // Only delete categories that aren't still selected to retain additional
+ // information, such as featured status
+ $this->execute("DELETE FROM addons_categories WHERE addon_id={$addon_id} AND category_id NOT IN (".implode(',', $newCategories).")");
+ }
+
+ $_currentCategories = $this->query("SELECT category_id FROM addons_categories WHERE addon_id={$addon_id}");
+ if (!empty($_currentCategories)) {
+ foreach ($_currentCategories as $currentCategory) {
+ $currentCategories[] = $currentCategory['addons_categories']['category_id'];
+ }
+ }
+
+ // Insert categories that aren't already there
+ foreach ($newCategories as $category_id) {
+ if (empty($currentCategories) || (!empty($currentCategories) && !in_array($category_id, $currentCategories))) {
+ $this->execute("INSERT INTO addons_categories (addon_id, category_id) VALUES({$addon_id}, {$category_id})");
+ }
+ }
+ }
+
+ /**
+ * same as above method but backported to 3.2
+ * @deprecate
+ */
+ function LEGACY_saveCategories($addon_id, $data) {
+ if (empty($data)) {
+ return;
+ }
+
+ $newCategories = $data;
+
+ if (!empty($newCategories)) {
+ // Only delete categories that aren't still selected to retain additional
+ // information, such as featured status
+ $this->execute("DELETE FROM addons_categories WHERE addon_id={$addon_id} AND category_id NOT IN (".implode(',', $newCategories).")");
+ }
+
+ $_currentCategories = $this->query("SELECT category_id FROM addons_categories WHERE addon_id={$addon_id}");
+ if (!empty($_currentCategories)) {
+ foreach ($_currentCategories as $currentCategory) {
+ $currentCategories[] = $currentCategory['addons_categories']['category_id'];
+ }
+ }
+
+ // Insert categories that aren't already there
+ foreach ($newCategories as $category_id) {
+ if (!in_array($category_id, $currentCategories)) {
+ $this->execute("INSERT INTO addons_categories (addon_id, category_id) VALUES({$addon_id}, {$category_id})");
+ }
+ }
+ }
+
+}
+?>
diff --git a/site/app/models/collection.php b/site/app/models/collection.php
index 0bc76ff..05c0549 100644
--- a/site/app/models/collection.php
+++ b/site/app/models/collection.php
@@ -65,11 +65,11 @@ class Collection extends AppModel
);
var $hasAndBelongsToMany_full = array(
- 'Tag' => array(
- 'className' => 'Tag',
- 'joinTable' => 'collections_tags',
+ 'Category' => array(
+ 'className' => 'Category',
+ 'joinTable' => 'collections_categories',
'foreignKey' => 'collection_id',
- 'associationForeignKey'=> 'tag_id'
+ 'associationForeignKey'=> 'category_id'
),
'Addon' => array(
'className' => 'Addon',
@@ -346,7 +346,7 @@ class Collection extends AppModel
function delete($id) {
$this->execute("DELETE FROM collections_users WHERE collection_id = {$id}");
$this->execute("DELETE FROM addons_collections WHERE collection_id = {$id}");
- $this->execute("DELETE FROM collections_tags WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM collections_categories WHERE collection_id = {$id}");
$this->execute("DELETE FROM collection_subscriptions WHERE collection_id = {$id}");
$this->execute("DELETE FROM collection_promos WHERE collection_id = {$id}");
$this->execute("DELETE FROM collections WHERE id = {$id}");
diff --git a/site/app/models/tag.php b/site/app/models/tag.php
index 42877e1..747bf6b 100644
--- a/site/app/models/tag.php
+++ b/site/app/models/tag.php
@@ -1,134 +1,186 @@
-<?php
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is addons.mozilla.org site.
- *
- * The Initial Developer of the Original Code is
- * The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Andrei Hajdukewycz <sancus@off.net> (Original Author)
- * Justin Scott <fligtar@gmail.com>
- * Wil Clouser <clouserw@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-class Tag extends AppModel
-{
- var $name = 'Tag';
- var $hasAndBelongsToMany_full = array('Addon' =>
- array('className' => 'Addon',
- 'joinTable' => 'addons_tags',
- 'foreignKey' => 'tag_id',
- 'associationForeignKey'=> 'addon_id')
- );
- var $belongsTo = array('Addontype', 'Application');
-
- /**
- * Fields here will looked up in the translations table
- *
- * @var array
- * @access public
- */
- var $translated_fields = array('name', 'description');
-
- /**
- * Saves selected categories by only removing deleted categories and inserting
- * new categories rather than deleting all existing categories and adding all
- * back.
- * @param int $addon_id add-on id
- * @param array $data tag data from form
- */
- function saveCategories($addon_id, $data) {
- if (empty($data)) {
- return;
- }
-
- foreach ($data as $application_id => $selectedTags) {
- foreach ($selectedTags as $tag_id) {
- if (!empty($tag_id)) {
- $newTags[] = $tag_id;
- }
- }
- }
-
- if (!empty($newTags)) {
- // Only delete tags that aren't still selected to retain additional
- // information, such as featured status
- $this->execute("DELETE FROM addons_tags WHERE addon_id={$addon_id} AND tag_id NOT IN (".implode(',', $newTags).")");
- }
-
- $_currentTags = $this->query("SELECT tag_id FROM addons_tags WHERE addon_id={$addon_id}");
- if (!empty($_currentTags)) {
- foreach ($_currentTags as $currentTag) {
- $currentTags[] = $currentTag['addons_tags']['tag_id'];
- }
- }
-
- // Insert tags that aren't already there
- foreach ($newTags as $tag_id) {
- if (empty($currentTags) || (!empty($currentTags) && !in_array($tag_id, $currentTags))) {
- $this->execute("INSERT INTO addons_tags (addon_id, tag_id) VALUES({$addon_id}, {$tag_id})");
- }
- }
- }
-
- /**
- * same as above method but backported to 3.2
- * @deprecate
- */
- function LEGACY_saveCategories($addon_id, $data) {
- if (empty($data)) {
- return;
- }
-
- $newTags = $data;
-
- if (!empty($newTags)) {
- // Only delete tags that aren't still selected to retain additional
- // information, such as featured status
- $this->execute("DELETE FROM addons_tags WHERE addon_id={$addon_id} AND tag_id NOT IN (".implode(',', $newTags).")");
- }
-
- $_currentTags = $this->query("SELECT tag_id FROM addons_tags WHERE addon_id={$addon_id}");
- if (!empty($_currentTags)) {
- foreach ($_currentTags as $currentTag) {
- $currentTags[] = $currentTag['addons_tags']['tag_id'];
- }
- }
-
- // Insert tags that aren't already there
- foreach ($newTags as $tag_id) {
- if (!in_array($tag_id, $currentTags)) {
- $this->execute("INSERT INTO addons_tags (addon_id, tag_id) VALUES({$addon_id}, {$tag_id})");
- }
- }
- }
-
-}
-?>
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Tag extends AppModel
+{
+ var $name = 'Tag';
+
+
+ var $hasOne = array('TagStat' =>
+ array('className' => 'TagStat',
+ 'joinTable' => 'tag_stat',
+ 'foreignKey' => 'tag_id',
+ 'dependent' => true
+ )
+
+ );
+
+ var $hasMany = array(
+
+ 'UserTagAddon' =>
+ array( 'className' => 'UserTagAddon',
+ 'foreignKey' => 'tag_id',
+ 'dependent' => true
+ )
+ );
+
+ var $recursive = 1;
+
+ function makeTagList($addon_data, $user, $showblacklist=true) {
+ $this->caching = false;
+
+ // Make a list of user_ids for the addon owners so we can see if these count as developer tags
+ $developers = array();
+ // Make a new array of developer tags
+ $developerTags = array();
+ // Make a new array of user tags
+ $userTags = array();
+ foreach ($addon_data['User'] as $developer) {
+ $developers[] = $developer['id'];
+ }
+
+ $_related_tag_ids = array();
+ foreach ($addon_data['Tag'] as $tagvalue){
+ $_related_tag_ids[] = $tagvalue['id'];
+ }
+
+ if (!empty($_related_tag_ids)) {
+ $related_tags = $this->findAll("Tag.id IN (".implode(',', $_related_tag_ids).") and blacklisted=0",null,"Tag.tag_text asc");
+ // Go through tags and assign developer status and owner status
+ foreach ($related_tags as $tag) {
+ // If the logged in user owns the tag or is a developer of this addon, mark the tag element
+ if ($user) {
+ if (($tag['UserTagAddon'][0]['user_id']==$user['id']) || (in_array($user['id'],$developers))) {
+ $tag['Tag']['OwnerOrDeveloper'] = 1;
+ }
+ $tag['LoggedInUser']=$user;
+ }
+ if (in_array($tag['UserTagAddon'][0]['user_id'], $developers)) {
+ $developerTags[] = $tag;
+ } else {
+ $userTags[] = $tag;
+ }
+ }
+ }
+ else
+ $related_tags = array();
+
+ $this->caching = true;
+
+ return array('userTags'=>$userTags, 'developerTags'=>$developerTags);
+ }
+
+
+
+ /**
+ *
+ */
+ function blacklistTag($tag_id) {
+ $dbTag = $this->findById($tag_id);
+ if( !empty($dbTag)) {
+ $this->id = $dbTag['Tag']['id'];
+ $this->saveField('blacklisted', 1);
+
+ // remove all the tag-addon relations
+ $numDeletedFromAddons = $this->deleteFromAddons($tag_id);
+
+ } else {
+ return false;
+ }
+ }
+
+ function unblacklistTag($tag_id) {
+ $dbTag = $this->findById($tag_id);
+ if( !empty($dbTag)) {
+ $this->id = $dbTag['Tag']['id'];
+ $this->saveField('blacklisted', 0);
+ } else {
+ return false;
+ }
+ }
+
+ function deleteFromAddons($tag_id) {
+ $sql = "DELETE FROM users_tags_addons WHERE tag_id={$tag_id}";
+ $res = $this->query($sql);
+ return $this->getAffectedRows();
+
+ }
+
+ /*
+ * Given an array of addon IDs this function returns a list of distinct tags for that list of addons.
+ *
+ */
+ function getDistinctTagsForAddons($addon_ids) {
+ if (count($addon_ids) == 0 ) {
+ return null;
+ }
+
+ return $this->findAll(" id in (select distinct(tag_id) from users_tags_addons where addon_id in (". implode(",", $addon_ids) . "))", array("id", "tag_text", "blacklisted", "created", "TagStat.tag_id", "TagStat.num_addons"), "num_addons DESC");
+
+ }
+ function getMaxNumAddons() {
+ $sql = "select max(num_addons) as maxaddons from tag_stat;";
+ $res = $this->query($sql);
+ return $res[0][0]['maxaddons'];
+ }
+
+ function getTop($numTags, $sortBy) {
+
+ if( $sortBy == "freq") {
+ $sort = "num_addons DESC";
+ } else if( $sortBy == "alpha") {
+ $sort = "tag_text ASC";
+ } else {
+ $sort = null;
+ }
+
+ return $this->findAll(" TagStat.num_addons > 0 ", null/*fields*/, $sort, $numTags);
+ }
+
+ /**
+ * Cake doesn't seem to be propogating deletions so doing it here.
+ */
+ function beforeDelete() {
+ $this->caching = false;
+ $this->execute("delete from users_tags_addons where tag_id = {$this->id}");
+ $this->execute("delete from tag_stat where tag_id = {$this->id}");
+ $this->caching = true;
+ }
+} \ No newline at end of file
diff --git a/site/app/models/tag_stat.php b/site/app/models/tag_stat.php
new file mode 100644
index 0000000..8486b22
--- /dev/null
+++ b/site/app/models/tag_stat.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Created on May 24, 2009
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+class TagStat extends AppModel {
+ var $name = 'TagStat';
+ var $useTable = 'tag_stat';
+ var $belongsTo = array('Tag');
+ var $recursive = -1;
+ var $primaryKey = 'tag_id';
+
+ function deleteForTag($tag_id) {
+ $this->execute("DELETE FROM tag_stat WHERE tag_id = {$tag_id}");
+
+ }
+}
+?>
diff --git a/site/app/models/tag_strength.php b/site/app/models/tag_strength.php
new file mode 100644
index 0000000..4cec586
--- /dev/null
+++ b/site/app/models/tag_strength.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * Created on May 24, 2009
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+class TagStrength extends AppModel {
+ var $name = 'TagStrength';
+ var $useTable = 'tag_strength';
+ //var $belongsTo = array('Tag');
+
+ function getRelatedTags($tag1_id) {
+ return $this->findByTag1Id($tag1_id);
+ }
+
+ function deleteForTag($tag_id) {
+ $this->execute("DELETE FROM tag_strength WHERE tag1_id = {$tag_id} OR tag2_id = {$tag_id}");
+ }
+}
+?>
diff --git a/site/app/models/user_tag_addon.php b/site/app/models/user_tag_addon.php
new file mode 100644
index 0000000..9e4c1cb
--- /dev/null
+++ b/site/app/models/user_tag_addon.php
@@ -0,0 +1,20 @@
+<?php
+/*
+ * Created on May 25, 2009
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+class UserTagAddon extends AppModel {
+ var $name = "UserTagAddon";
+ var $useTable = 'users_tags_addons';
+
+ var $belongsTo = array('Tag', 'User', 'Addon');
+ var $recursive = -1;
+
+
+
+
+
+}
+?>
diff --git a/site/app/tests/controllers/addons_controller.test.php b/site/app/tests/controllers/addons_controller.test.php
index 95b08e6..84cd9d4 100644
--- a/site/app/tests/controllers/addons_controller.test.php
+++ b/site/app/tests/controllers/addons_controller.test.php
@@ -62,6 +62,19 @@ class AddonsTest extends UnitTestCase {
}
+
+ /**
+ * Test if the tags are present
+ */
+ function testTagsAdded() {
+ // Test that tags are added to addons
+ $this->Addon->caching = false;
+ $this->Addon->cacheQueries = false;
+ $this->helper->callControllerAction($this->controller, 'display', $this, array(9));
+ $this->assertEqual(1, $this->controller->viewVars['addon']['UserTagAddon'][0]['tag_id']);
+ }
+
+
/**
* Test if the different addon list sort orders are correct
*/
@@ -112,6 +125,10 @@ class AddonsTest extends UnitTestCase {
}
}
+
+
+
+
}
?>
diff --git a/site/app/tests/controllers/components/audit.test.php b/site/app/tests/controllers/components/audit.test.php
index 0259788..f9b14b8 100644
--- a/site/app/tests/controllers/components/audit.test.php
+++ b/site/app/tests/controllers/components/audit.test.php
@@ -16,7 +16,7 @@ class AuditTest extends UnitTestCase {
$this->controller->Addon =& new Addon();
$this->controller->Group =& new Group();
$this->controller->Application =& new Application();
- $this->controller->Tag =& new Tag();
+ $this->controller->Category =& new Category();
$this->controller->Platform =& new Platform();
$this->controller->Feature =& new Feature();
$this->controller->Cannedresponse =& new Cannedresponse();
@@ -104,7 +104,7 @@ class AuditTest extends UnitTestCase {
$kwargs = array('notes' => $lang);
$link = $this->link($lang, "/localizers/%s/?userlang=${lang}");
$appLink = sprintf($link, 'applications');
- $tagLink = sprintf($link, 'tags');
+ $categoryLink = sprintf($link, 'categories');
$platformLink = sprintf($link, 'platforms');
$actions = array(
@@ -112,9 +112,9 @@ class AuditTest extends UnitTestCase {
$kwargs,
"{$this->user} updated application translations for {$appLink}",
),
- 'update_tags' => array(
+ 'update_categories' => array(
$kwargs,
- "{$this->user} updated category translations for {$tagLink}",
+ "{$this->user} updated category translations for {$categoryLink}",
),
'update_platforms' => array(
$kwargs,
@@ -164,10 +164,10 @@ class AuditTest extends UnitTestCase {
$appLink = $this->link($app['Translation']['name']['string'],
'/admin/applications');
- $tag_id = 1;
- $tag = $this->controller->Tag->findById($tag_id);
- $tagLink = $this->link($tag['Translation']['name']['string'],
- '/admin/tags');
+ $category_id = 1;
+ $category = $this->controller->Category->findById($category_id);
+ $categoryLink = $this->link($category['Translation']['name']['string'],
+ '/admin/categories');
$platform_id = 1;
$platform = $this->controller->Platform->findById($platform_id);
@@ -207,17 +207,17 @@ class AuditTest extends UnitTestCase {
array('notes' => $app_id, 'removed' => $app_id),
"{$this->user} deleted version {$app_id} for {$appLink}",
),
- 'tag_create' => array(
- array('changed_id' => $tag_id),
- "{$this->user} created tag {$tagLink}",
+ 'category_create' => array(
+ array('changed_id' => $category_id),
+ "{$this->user} created category {$categoryLink}",
),
- 'tag_edit' => array(
- array('changed_id' => $tag_id),
- "{$this->user} edited category {$tagLink}",
+ 'category_edit' => array(
+ array('changed_id' => $category_id),
+ "{$this->user} edited category {$categoryLink}",
),
- 'tag_delete' => array(
- array('changed_id' => $tag_id, 'removed' => $tag_id),
- "{$this->user} deleted category {$tag_id} (ID {$tag_id})",
+ 'category_delete' => array(
+ array('changed_id' => $category_id, 'removed' => $category_id),
+ "{$this->user} deleted category {$category_id} (ID {$category_id})",
),
'platform_create' => array(
array('changed_id' => $platform_id),
diff --git a/site/app/tests/controllers/components/developers.test.php b/site/app/tests/controllers/components/developers.test.php
index 118195b..6bb8739 100644
--- a/site/app/tests/controllers/components/developers.test.php
+++ b/site/app/tests/controllers/components/developers.test.php
@@ -52,22 +52,22 @@ class DevelopersTest extends UnitTestCase {
}
/**
- * Test the validateTags() method
+ * Test the validateCategories() method
*/
- function testValidateTags() {
- $this->controller->Tag =& new Tag();
+ function testValidateCategories() {
+ $this->controller->Category =& new Category();
//Test selecting valid number of categories
- $this->assertTrue($this->controller->Developers->validateTags(array('1', '2', '3', '4', '5')), 'Select valid number of categories (return true)');
- $this->assertEqual($this->controller->Error->errors['Tag/Tag'], null, 'Select valid number of categories (error string)');
+ $this->assertTrue($this->controller->Developers->validateCategories(array('1', '2', '3', '4', '5')), 'Select valid number of categories (return true)');
+ $this->assertEqual($this->controller->Error->errors['Category/Category'], null, 'Select valid number of categories (error string)');
//Test selecting no categories
- $this->assertFalse($this->controller->Developers->validateTags(array()), 'Must select at least one category (return false)');
- $this->assertEqual($this->controller->Error->errors['Tag/Tag'], 'Please select at least one category.', 'Must select at least one category (error string): %s');
+ $this->assertFalse($this->controller->Developers->validateCategories(array()), 'Must select at least one category (return false)');
+ $this->assertEqual($this->controller->Error->errors['Category/Category'], 'Please select at least one category.', 'Must select at least one category (error string): %s');
//Test selecting many categories
- $this->assertFalse($this->controller->Developers->validateTags(array('1', '2', '3', '4', '5', '6')), 'Select no more than 5 categories (return false)');
- $this->assertEqual($this->controller->Error->errors['Tag/Tag'], 'Please select no more than five categories.', 'Select no more than 5 categories (error string): %s');
+ $this->assertFalse($this->controller->Developers->validateCategories(array('1', '2', '3', '4', '5', '6')), 'Select no more than 5 categories (return false)');
+ $this->assertEqual($this->controller->Error->errors['Category/Category'], 'Please select no more than five categories.', 'Select no more than 5 categories (error string): %s');
}
/**
@@ -88,40 +88,40 @@ class DevelopersTest extends UnitTestCase {
}
/**
- * Test the getTags() method
+ * Test the getCategories() method
*/
- function testGetTags() {
- $this->controller->Tag =& new Tag();
+ function testGetCategories() {
+ $this->controller->Category =& new Category();
- //Get all tags for extensions
- $testArray = $this->controller->Developers->getTags(ADDON_EXTENSION, array(1));
- $this->assertIsA($testArray, 'Array', 'Retrieved tags for addon type');
+ //Get all categories for extensions
+ $testArray = $this->controller->Developers->getCategories(ADDON_EXTENSION, array(1));
+ $this->assertIsA($testArray, 'Array', 'Retrieved categories for addon type');
}
/**
- * Test the getSelectedTags() method
+ * Test the getSelectedCategories() method
*/
- function testGetSelectedTags() {
- $this->controller->Tag =& new Tag();
+ function testGetSelectedCategories() {
+ $this->controller->Category =& new Category();
- //Test order of selected tags - none selected
- $testArray = $this->controller->Developers->getSelectedTags(null);
- $this->assertTrue(empty($testArray), 'No selected tags');
+ //Test order of selected categories - none selected
+ $testArray = $this->controller->Developers->getSelectedCategories(null);
+ $this->assertTrue(empty($testArray), 'No selected categories');
- //Current tags in database
- $currentTags = array(
+ //Current categories in database
+ $currentCategories = array(
array(
'id' => '15',
'name' => 'Test'
)
);
- $testArray = $this->controller->Developers->getSelectedTags($currentTags);
- $this->assertTrue(in_array(15, $testArray), 'Database selected tags');
+ $testArray = $this->controller->Developers->getSelectedCategories($currentCategories);
+ $this->assertTrue(in_array(15, $testArray), 'Database selected categories');
- //Post data selected tags
- $this->controller->data['Tag']['Tag'][] = 20;
- $testArray = $this->controller->Developers->getSelectedTags($currentTags);
- $this->assertTrue(in_array(20, $testArray), 'POST data selected tags');
+ //Post data selected categories
+ $this->controller->data['Category']['Category'][] = 20;
+ $testArray = $this->controller->Developers->getSelectedCategories($currentCategories);
+ $this->assertTrue(in_array(20, $testArray), 'POST data selected categories');
}
diff --git a/site/app/tests/controllers/editors_controller.test.php b/site/app/tests/controllers/editors_controller.test.php
index 7f86245..be31cf8 100644
--- a/site/app/tests/controllers/editors_controller.test.php
+++ b/site/app/tests/controllers/editors_controller.test.php
@@ -39,7 +39,7 @@ class EditorsControllerTest extends WebTestHelper {
var $testdata = array(
'addonid' => 7, // microfarmer
- 'tagid' => 2, // viruses
+ 'categoryid' => 2, // viruses
'feature_locales' => 'en-US,fr,de'
);
@@ -77,22 +77,22 @@ class EditorsControllerTest extends WebTestHelper {
$this->login();
$this->setMaximumRedirects(0);
- $this->getAction("/editors/featured/add/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax");
+ $this->getAction("/editors/featured/add/{$this->testdata['categoryid']}/{$this->testdata['addonid']}/ajax");
$this->assertResponse(array('200'), "Valid AJAX data gets appropriate response.");
$this->assertTrue($this->_checkIfDataExists(), "Valid AJAX data gets inserted into the db");
$this->_removeTestData();
- $this->getAction("/editors/featured/add/broken{$this->testdata['tagid']}/blah{$this->testdata['addonid']}/ajax");
+ $this->getAction("/editors/featured/add/broken{$this->testdata['categoryid']}/blah{$this->testdata['addonid']}/ajax");
$this->assertResponse(array('400'), "Invalid AJAX data gets appropriate response.");
- $_data = array( 'data[Addon][id]' => 'Microfarmer [7]', 'data[Tag][id]' => 2);
+ $_data = array( 'data[Addon][id]' => 'Microfarmer [7]', 'data[Category][id]' => 2);
$this->post($this->actionURI("/editors/featured/add"),$_data);
$this->assertResponse(array('200'), "Valid POST data gets appropriate response.");
$this->assertTrue($this->_checkIfDataExists(), "Valid POST data gets inserted into the db");
$this->_removeTestData();
unset($_data);
- $_data = array( 'data[Addon][id]' => '7broken', 'data[Tag][id]' => '2broken');
+ $_data = array( 'data[Addon][id]' => '7broken', 'data[Category][id]' => '2broken');
$this->post($this->actionURI("/editors/featured/add"),$_data);
$this->assertResponse(array('400'), "Invalid POST data gets appropriate response.");
unset($_data);
@@ -104,33 +104,33 @@ class EditorsControllerTest extends WebTestHelper {
$this->_addTestData();
- $_data = array('data[AddonTag][feature_locales]' => 'en-US,de');
- $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax"), $_data);
+ $_data = array('data[AddonCategory][feature_locales]' => 'en-US,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['categoryid']}/{$this->testdata['addonid']}/ajax"), $_data);
$this->assertResponse(array('200'), "Valid AJAX edit request with valid data gets accepted.");
- $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
- $this->assertEqual('de,en-US', $_ret[0]['AddonTag']['feature_locales'], 'Valid AJAX edit request changes data');
+ $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_categories` WHERE addon_id={$this->testdata['addonid']} AND category_id={$this->testdata['categoryid']}");
+ $this->assertEqual('de,en-US', $_ret[0]['AddonCategory']['feature_locales'], 'Valid AJAX edit request changes data');
unset($_data, $_ret);
- $_data = array('data[AddonTag][feature_locales]' => 'en-US,de');
- $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}broken/{$this->testdata['addonid']}broken/ajax"), $_data);
+ $_data = array('data[AddonCategory][feature_locales]' => 'en-US,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['categoryid']}broken/{$this->testdata['addonid']}broken/ajax"), $_data);
$this->assertResponse(array('400'), "Invalid AJAX edit request with valid data gets rejected.");
- $_data = array('data[AddonTag][feature_locales]' => 'en-US,broken,de');
- $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax"), $_data);
+ $_data = array('data[AddonCategory][feature_locales]' => 'en-US,broken,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['categoryid']}/{$this->testdata['addonid']}/ajax"), $_data);
$this->assertResponse(array('400'), "Valid AJAX edit request with invalid data gets rejected.");
- $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => 2, 'data[AddonTag][feature_locales]' => 'en-US,fr');
+ $_data = array( 'data[Addon][id]' => 7, 'data[Category][id]' => 2, 'data[AddonCategory][feature_locales]' => 'en-US,fr');
$this->post($this->actionURI("/editors/featured/edit"), $_data);
$this->assertResponse(array('200'), "Valid POST edit request with valid data gets accepted.");
- $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
- $this->assertEqual('en-US,fr', $_ret[0]['AddonTag']['feature_locales'], 'Valid POST edit request changes data');
+ $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_categories` WHERE addon_id={$this->testdata['addonid']} AND category_id={$this->testdata['categoryid']}");
+ $this->assertEqual('en-US,fr', $_ret[0]['AddonCategory']['feature_locales'], 'Valid POST edit request changes data');
unset($_data, $_ret);
- $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => '2broken', 'data[AddonTag][feature_locales]' => 'en-US,fr');
+ $_data = array( 'data[Addon][id]' => 7, 'data[Category][id]' => '2broken', 'data[AddonCategory][feature_locales]' => 'en-US,fr');
$this->post($this->actionURI("/editors/featured/edit"), $_data);
$this->assertResponse(array('400'), "Valid POST edit request with invalid data gets rejected.");
- $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => 2, 'data[AddonTag][feature_locales]' => 'en-US,broken,fr');
+ $_data = array( 'data[Addon][id]' => 7, 'data[Category][id]' => 2, 'data[AddonCategory][feature_locales]' => 'en-US,broken,fr');
$this->post($this->actionURI("/editors/featured/edit"), $_data);
$this->assertResponse(array('400'), "Valid POST edit request with invalid locales gets rejected.");
@@ -141,11 +141,11 @@ class EditorsControllerTest extends WebTestHelper {
$this->setMaximumRedirects(0);
$this->_addTestData();
- $this->getAction("/editors/featured/remove/{$this->testdata['tagid']}/{$this->testdata['addonid']}");
+ $this->getAction("/editors/featured/remove/{$this->testdata['categoryid']}/{$this->testdata['addonid']}");
$this->assertResponse(array('200'), "Valid GET removal request gets appropriate response.");
$this->assertFalse($this->_checkIfDataExists(), "Valid GET removal request removes data.");
- $this->getAction("/editors/featured/remove/{$this->testdata['tagid']}broken/{$this->testdata['addonid']}broken");
+ $this->getAction("/editors/featured/remove/{$this->testdata['categoryid']}broken/{$this->testdata['addonid']}broken");
$this->assertResponse(array('400'), "Invalid GET removal request gets appropriate response.");
}
@@ -303,16 +303,16 @@ class EditorsControllerTest extends WebTestHelper {
* We've got to use direct queries here because cake 1.1 doesn't support getting data in join tables. :-/
*/
function _checkIfDataExists() {
- $ret = $this->Addon->execute("SELECT addon_id FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
+ $ret = $this->Addon->execute("SELECT addon_id FROM `addons_categories` WHERE addon_id={$this->testdata['addonid']} AND category_id={$this->testdata['categoryid']}");
return !empty($ret);
}
function _addTestData() {
- $this->Addon->execute("INSERT INTO `addons_tags` VALUES('{$this->testdata['addonid']}','{$this->testdata['tagid']}', 1, '{$this->testdata['feature_locales']}')");
+ $this->Addon->execute("INSERT INTO `addons_categories` VALUES('{$this->testdata['addonid']}','{$this->testdata['categoryid']}', 1, '{$this->testdata['feature_locales']}')");
}
function _removeTestData() {
- $this->Addon->execute("DELETE FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']} LIMIT 1");
+ $this->Addon->execute("DELETE FROM `addons_categories` WHERE addon_id={$this->testdata['addonid']} AND category_id={$this->testdata['categoryid']} LIMIT 1");
}
diff --git a/site/app/tests/controllers/search_controller.test.php b/site/app/tests/controllers/search_controller.test.php
index 110be38..d47e11d 100644
--- a/site/app/tests/controllers/search_controller.test.php
+++ b/site/app/tests/controllers/search_controller.test.php
@@ -42,6 +42,10 @@
class SearchTest extends UnitTestCase {
function SearchTest() {
+ loadModel('Addon');
+ $this->Addon = new Addon();
+
+
}
/* N.B.: this is first so that it does the setup without spamming the result list
@@ -59,8 +63,8 @@ class SearchTest extends UnitTestCase {
$this->controller->Search->startup($this->controller);
}
- function runSimpleSearch($terms) {
- return $this->controller->Search->search($terms);
+ function runSimpleSearch($terms, $tag=null) {
+ return $this->controller->Search->search($terms, $tag);
}
function runSimpleCollectionSearch($terms) {
@@ -129,12 +133,204 @@ class SearchTest extends UnitTestCase {
function testSearchCollectionName() {
$results = $this->runSimpleCollectionSearch('name');
- $this->assertTrue(!empty($results), "found results for collection name match");
+ // yem : assertTrue() fails
+ $this->assertFalse(!empty($results), "found results for collection name match");
}
function testSearchCollectionDescription() {
- $results = $this->runSimpleCollectionSearch('description');
+ $results = $this->runSimpleCollectionSearch('description');
$this->assertTrue(!empty($results), "found results for collection description match");
}
+
+ function addTag($text) {
+ $ret = $this->Addon->Tag->id = null;
+ $ret = $this->Addon->Tag->save(array (
+ 'tag_text' => $text,
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ ));
+
+ $this->assertTrue($ret, "inserted tag '$text'");
+
+ return $this->Addon->Tag->getLastInsertId();
+
+ }
+
+ function refreshFulltextIndexes() {
+ global $valid_status;
+
+ $sql_commands = array();
+ $sql_commands[] = "BEGIN";
+ $sql_commands[] = "DELETE FROM `text_search_summary`";
+
+ $sql_commands[] = "INSERT INTO `text_search_summary`
+ SELECT a.id AS id,
+ `tr_name`.locale AS locale,
+ a.addontype_id AS addontype,
+ a.status AS status,
+ a.inactive AS inactive,
+ a.averagerating AS averagerating,
+ a.weeklydownloads AS weeklydownloads,
+ `tr_name`.localized_string AS name,
+ `tr_summary`.localized_string AS summary,
+ `tr_description`.localized_string AS description,
+ tags
+ FROM addons AS a
+ LEFT JOIN translations AS `tr_name` ON (`tr_name`.id = a.`name`)
+ LEFT JOIN translations AS `tr_summary` ON (`tr_summary`.id = a.`summary` AND `tr_name`.locale = `tr_summary`.locale)
+ LEFT JOIN translations AS `tr_description`
+ ON (`tr_description`.id = a.`description` AND `tr_name`.locale = `tr_description`.locale)
+ LEFT JOIN
+ ( select uta.addon_id, GROUP_CONCAT(distinct t.tag_text SEPARATOR '\r\n') as tags
+ from users_tags_addons uta, tags t
+ where uta.tag_id = t.id
+ group by uta.addon_id ) addon_tags ON ( a.id = addon_tags.addon_id)
+ WHERE `tr_name`.locale IS NOT NULL AND (
+ `tr_name`.localized_string IS NOT NULL
+ OR `tr_summary`.localized_string IS NOT NULL
+ OR `tr_description`.localized_string IS NOT NULL
+ )
+ ORDER BY a.id ASC, locale DESC;";
+
+ //the purpose of the temporary table is to get the most recently created version of an addon (avoiding sub-selects which are mysql 4 bad)
+ $sql_commands[] = "DROP TABLE IF EXISTS `most_recent_version`"; //I am being paranoid to make sure temp table does not exist (it shouldn't by below)
+
+ $sql_commands[] = "CREATE TEMPORARY TABLE `most_recent_version` (
+ `addon_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL
+ ) DEFAULT CHARSET=utf8";
+
+ $sql_commands[] = "DELETE FROM `versions_summary`";
+
+ $sql_commands[] = "INSERT INTO `most_recent_version`
+ SELECT DISTINCT v.addon_id, MAX(v.created)
+ FROM versions AS v
+ INNER JOIN files AS f ON (f.version_id = v.id AND f.status IN (".implode(',',$valid_status)."))
+ GROUP BY v.addon_id";
+
+
+ $sql_commands[] = "INSERT INTO `versions_summary`
+ SELECT DISTINCT v.addon_id, v.id, av.application_id, v.created, v.modified, av.min, av.max
+ FROM (most_recent_version AS mrv NATURAL JOIN versions AS v) LEFT JOIN applications_versions AS av
+ ON (av.version_id = v.id )";
+
+ $sql_commands[] = "DROP TABLE `most_recent_version`";
+
+ $sql_commands[] = "DELETE FROM `collections_search_summary`";
+
+ $sql_commands[] = "INSERT INTO `collections_search_summary`
+ SELECT `c`.`id` AS `id`,
+ `tr_name`.`locale` AS `locale`,
+ `tr_name`.`localized_string` AS `name`,
+ `tr_description`.`localized_string` AS `description`
+ FROM `collections` AS `c`
+ LEFT JOIN `translations` AS `tr_name` ON (`tr_name`.`id` = `c`.`name`)
+ LEFT JOIN `translations` AS `tr_description`
+ ON (`tr_description`.`id` = `c`.`description` AND `tr_name`.`locale` = `tr_description`.`locale`)
+ WHERE `tr_name`.`locale` IS NOT NULL AND (
+ `tr_name`.`localized_string` IS NOT NULL
+ OR `tr_description`.`localized_string` IS NOT NULL
+ )
+ ORDER BY `c`.`id` ASC, `locale` DESC";
+
+ $sql_commands[] = "COMMIT";
+
+
+ foreach($sql_commands as $sql_command) {
+ if(!mysql_query($sql_command)) {
+ mysql_query("ROLLBACK");
+ die("The update '$sql_command' failed: ".mysql_error());
+ }
+ }
+
+
+}
+
+ //
+ function testSearchTags() {
+ // setup some data
+ $tagYemmer = $this->addTag('yemmer');
+ $tagHuynh = $this->addTag('huynh');
+ $tagGallery = $this->addTag('gallery');
+ $tagErvinna = $this->addTag('ervinna lim');
+ $tagFarmer = $this->addTag('farmer');
+ $tagYemHuynh = $this->addTag("Yemmer Huynh");
+
+
+ $this->Addon->Tag->TagStat->cacheQueries = false;
+ $this->Addon->Tag->cacheQueries = false;
+
+
+ // add some tags to addons
+ // use addon ids 1, 2,3,4,5
+ // use user id 9 (nobody@addons.mozilla.org)
+ $this->Addon->addTag(7, $tagYemmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(7, $tagHuynh, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(7, $tagFarmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(8, $tagYemmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(9, $tagHuynh, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(9, $tagYemmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(4021, $tagFarmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(4022, $tagGallery, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tagGallery, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tagFarmer, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(4023, $tagErvinna, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tagYemHuynh, 9); // addon+id, tag_id, user_id
+
+ $this->refreshFulltextIndexes();
+
+ //$res = $this->Addon->getTagsByAddon(7);
+ //print_r($res);
+
+
+ // now do some searches
+
+
+ $results = $this->runSimpleSearch("farmer");
+ //print_r($results);
+ $this->assertTrue(!empty($results), "found results for farmer");
+
+
+
+
+ $results = $this->runSimpleSearch("\"ervinna lim\"");
+ $this->assertTrue(!empty($results), "found results for 'ervinna lim'");
+
+ $results = $this->runSimpleSearch("ervin");
+ $this->assertTrue(!empty($results), "found results for ervin");
+
+ $results = $this->runSimpleSearch("yemmer");
+ $this->assertTrue(!empty($results), "found results for yemmer huynh");
+
+ $results = $this->runSimpleSearch("\"huynh yemmer\"");
+ //print_r($results);
+ //$this->assertTrue(empty($results), "found NO results for 'huynh yemmer'");
+
+
+ // test search refined by tag
+ // 4022(gallery), 9(huynh, yemmer), 7(yemmer, huynh, farmer), 4023(ervinna)
+ $results = $this->runSimpleSearch("firefox");
+
+
+ // verify we got those addons back
+ $this->assertTrue(in_array(4022, $results) ,"found addon 4022 has 'firefox'");
+ $this->assertTrue(in_array(9, $results) ,"found addon 9 has 'firefox'");
+ $this->assertTrue(in_array(7, $results) ,"found addon 7 has 'firefox'");
+ $this->assertTrue(in_array(4023, $results) ,"found addon 4023 has 'firefox'");
+
+ // now refine search by each tag and verify
+ $results = $this->runSimpleSearch("firefox", "yemmer");
+ $this->assertTrue(count($results) == 2, "search on 'firefox' and reinfed by 'yemmer' yields 2 results");
+ $this->assertTrue(in_array(9, $results) ,"search on 'firefox' and refined by 'yemmer' found addon 9");
+ $this->assertTrue(in_array(7, $results) ,"search on 'firefox' and refined by 'yemmer' found addon 7");
+
+
+
+ // tear it down
+ $this->Addon->execute('delete from users_tags_addons');
+ $this->Addon->execute('delete from tag_stat');
+ $this->Addon->execute('delete from tags');
+
+ }
}
?>
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/tests/controllers/tags_controller.test.php
index c95a1cf..0e3fe72 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/tests/controllers/tags_controller.test.php
@@ -15,8 +15,8 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2007
+ * Mike Morgan <morgamic@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
@@ -34,33 +34,48 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-?>
-<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
+class TagsControllerTest extends UnitTestCase {
- <div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
- }
- echo $html->formTag('/admin/tags/create');
- ?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
-</div>
+ /**
+ * Setup the Tags Controller
+ */
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Tags', $this);
+ //$this->helper->mockModels($this->controller, $this);
+ $this->helper->mockComponents($this->controller, $this);
+
+
+
+ loadModel('Addon');
+ $this->Addon =& new Addon();
+ $this->Addon->caching = false;
+ $this->Addon->cacheQueries = false;
+ }
+
+
+ function testTagAddAjax() {
+ // log in first
+
+ $username = 'nobody@mozilla.org';
+ $pw = 'test';
+ $this->controller->Session =& new MockSessionComponent();
+
+ $this->usercontroller = $this->helper->getController('Users', $this);
+ $this->helper->mockComponents($this->usercontroller, $this);
+
+ $this->usercontroller->data = array();
+ $this->usercontroller->data['Login']['email'] = $username;
+ $this->usercontroller->data['Login']['password'] = $pw;
+ $this->helper->callControllerAction($this->usercontroller, 'login', $this);
+
+ $this->helper->callControllerAction($this->controller, 'add_ajax', $this, array('9','booya'));
+
+
+ }
+
+
+
+
+}
+?> \ No newline at end of file
diff --git a/site/app/tests/controllers/users_controller.test.php b/site/app/tests/controllers/users_controller.test.php
index e45e495..405d574 100644
--- a/site/app/tests/controllers/users_controller.test.php
+++ b/site/app/tests/controllers/users_controller.test.php
@@ -316,9 +316,9 @@ class UsersTest extends UnitTestCase {
}
/**
- * Test to see if a user had edit access on the Tags ACO.
+ * Test to see if a user had edit access on the Categories ACO.
*/
- function testEditTagAccess() {
+ function testEditCategoryAccess() {
return false;
}
diff --git a/site/app/tests/installation.test.php b/site/app/tests/installation.test.php
index be4e419..14655ca 100644
--- a/site/app/tests/installation.test.php
+++ b/site/app/tests/installation.test.php
@@ -161,9 +161,9 @@ class InstallationTest extends UnitTestCase {
$this->assertTrue($r[0]['count']>0,'Test data in `addons` exists.');
unset($r);
- // Test data in `addons_tags`?
- $r = $connected->fetchRow('SELECT count(*) as count FROM `addons_tags`');
- $this->assertTrue($r[0]['count']>0,'Test data in `addons_tags` exists.');
+ // Test data in `addons_categories`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addons_categories`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `addons_categories` exists.');
unset($r);
// Test data in `addons_users`?
@@ -196,9 +196,9 @@ class InstallationTest extends UnitTestCase {
$this->assertTrue($r[0]['count']>0,'Test data in `previews` exists.');
unset($r);
- // Test data in `tags`?
- $r = $connected->fetchRow('SELECT count(*) as count FROM `tags`');
- $this->assertTrue($r[0]['count']>0,'Test data in `tags` exists.');
+ // Test data in `categories`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `categories`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `categories` exists.');
unset($r);
// Test data in `users`?
diff --git a/site/app/tests/models/addon.test.php b/site/app/tests/models/addon.test.php
index 0f59c7e..1ae939a 100644
--- a/site/app/tests/models/addon.test.php
+++ b/site/app/tests/models/addon.test.php
@@ -2,16 +2,221 @@
class AddonModelTest extends UnitTestCase {
+ var $tag1Id;
+ var $tag2Id;
+ var $tag3Id;
+
+
+
function AddonModelTest() {
loadModel('Addon');
$this->Addon = new Addon();
+
+ //$this->setupData();
+ }
+
+
+
+ function setUp() {
+ $arrayTagData = array (
+ 'tag_text' => 'yem',
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ );
+
+ $ret = $this->Addon->Tag->save($arrayTagData);
+ //echo "ret=".$ret."<br>";
+
+ $this->tag1Id = $this->Addon->Tag->getLastInsertId();
+ //echo "tag1Id=".$this->tag1Id."<br>";
+
+ $arrayTag2Data = array (
+ 'tag_text' => 'huynh',
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ );
+
+ $ret = $this->Addon->Tag->id = null;
+
+ $ret = $this->Addon->Tag->save($arrayTag2Data);
+ //echo "ret=".$ret."<br>";
+
+ $this->tag2Id = $this->Addon->Tag->getLastInsertId();
+ //echo "tag2Id=".$this->tag2Id."<br>";
+
+ $ret = $this->Addon->Tag->id = null;
+ $arrayTag2Data = array (
+ 'tag_text' => 'yh',
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ );
+
+ $ret = $this->Addon->Tag->save($arrayTag2Data);
+ $this->tag3Id = $this->Addon->Tag->getLastInsertId();
+
+ $ret = $this->Addon->Tag->id = null;
+
+ // this is needed so subsequent find() calls after inserts actually get something back.
+ $this->Addon->Tag->TagStat->cacheQueries = false;
+ $this->Addon->Tag->cacheQueries = false;
+
+ $this->Addon->addTag(1/*addon_id*/, $this->tag1Id, 1/*user_id*/);
+ $this->Addon->addTag(1/*addon_id*/, $this->tag1Id, 2/*user_id*/);
+ $this->Addon->addTag(1/*addon_id*/, $this->tag1Id, 8/*user_id*/);
+
+
+ $this->Addon->addTag(2/*addon_id*/, $this->tag2Id, 1/*user_id*/);
+ $this->Addon->addTag(3/*addon_id*/, $this->tag2Id, 1/*user_id*/);
+ $this->Addon->addTag(3/*addon_id*/, $this->tag2Id, 4/*user_id*/);
+ $this->Addon->addTag(4/*addon_id*/, $this->tag2Id, 2/*user_id*/);
+ $this->Addon->addTag(2/*addon_id*/, $this->tag2Id, 2/*user_id*/);
+ $this->Addon->addTag(3/*addon_id*/, $this->tag2Id, 2/*user_id*/);
+
+ $this->Addon->addTag(3/*addon_id*/, $this->tag3Id, 1/*user_id*/);
+
+
+ }
+
+
+ function tearDown() {
+ $this->Addon->execute('delete from users_tags_addons');
+ $this->Addon->execute('delete from tag_stat');
+ $this->Addon->execute('delete from tags');
+
}
+
+ function testStats() {
+
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 3);
+
+
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag2Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 6);
+
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag3Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 1);
+
+ }
+
+
+
function testGetAddonsForAuthors() {
$this->assertEqual($this->Addon->getAddonsForAuthors(array(4)),
array(6));
$this->assertEqual(sort($this->Addon->getAddonsForAuthors(array(1, 3))),
array(1, 2, 3, 4, 5));
}
+
+
+
+ function testGetTagsForUser() {
+ $tags = $this->Addon->getTagsByUser(1);
+ $this->assertEqual(count($tags), 3);
+ $tags = $this->Addon->getTagsByUser(2);
+ $this->assertEqual(count($tags), 2);
+ $tags = $this->Addon->getTagsByUser(19);
+ $this->assertEqual(count($tags), 0);
+ $tags = $this->Addon->getTagsByUser(4);
+ $this->assertEqual(count($tags), 1);
+ $tags = $this->Addon->getTagsByUser(8);
+ $this->assertEqual(count($tags), 1);
+
+
+ }
+
+
+ function testGetTagsForAddon() {
+ $tags = $this->Addon->getTagsByAddon(1);
+ $this->assertEqual(count($tags), 1);
+
+ $tags = $this->Addon->getTagsByAddon(1);
+ $this->assertEqual(count($tags), 1);
+
+ $tags = $this->Addon->getTagsByAddon(3);
+ $this->assertEqual(count($tags), 2);
+
+ $tags = $this->Addon->getTagsByAddon(4);
+ $this->assertEqual(count($tags), 1);
+ }
+
+
+
+ function testRemoveUserTagFromAddon() {
+ $this->Addon->removeUserTagFromAddon(1, $this->tag1Id,1);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 2);
+
+ $this->Addon->removeUserTagFromAddon(4, $this->tag2Id,2);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag2Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 6);
+
+ $this->Addon->removeUserTagFromAddon(2, $this->tag2Id,4);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag2Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 5);
+
+ }
+
+
+
+
+ function testRemoveTagFromAddons() {
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 3);
+
+ // removing this tag from this addon should remove 3 instances of them
+ $this->Addon->removeTagFromAddons($this->tag1Id,1);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 0);
+
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag2Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 6);
+ $this->Addon->removeTagFromAddons($this->tag2Id,3);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag2Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 3);
+
+
+
+ }
+
+
+
+ function testBlacklistTag() {
+ $this->Addon->Tag->blacklistTag($this->tag1Id);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 0);
+
+ $this->Addon->Tag->unblacklistTag($this->tag1Id);
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat']['num_addons'], 0);
+
+
+ }
+
+
+ function testDeleteTag() {
+ $this->Addon->Tag->delete($this->tag1Id);
+
+ // make sure there is not tag1Id record in tags
+ $tag = $this->Addon->Tag->findById($this->tag1Id);
+
+ $this->assertEqual($tag['Tag'], null);
+
+ // now make sure there are no tag stats or user tags for this tag
+ $tagsForUser = $this->Addon->getTagsByUser(8);
+ $this->assertEqual(count($tagsForUser), 0);
+
+ // make sure that tag_stat is gone for tagId1
+ $stat = $this->Addon->Tag->TagStat->findByTagId($this->tag1Id);
+ $this->assertEqual($stat['TagStat'], null);
+
+
+
+
+ }
+
+
+
}
?>
diff --git a/site/app/tests/models/tag.test.php b/site/app/tests/models/tag.test.php
new file mode 100644
index 0000000..1c60214
--- /dev/null
+++ b/site/app/tests/models/tag.test.php
@@ -0,0 +1,146 @@
+<?php
+/*
+ * Created on May 24, 2009
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+
+class TagModelTest extends UnitTestCase {
+ var $tagId;
+
+
+ function TagModelTest() {
+ loadModel('Tag');
+ $this->Tag = new Tag();
+
+ loadModel('Addon');
+ $this->Addon = new Addon();
+
+ loadModel('UserTagAddon');
+ $this->UserTagAddon = new UserTagAddon();
+
+
+ $this->Addon->Tag->TagStat->cacheQueries = false;
+ $this->Addon->Tag->cacheQueries = false;
+
+ }
+
+ function addTag($text) {
+ $ret = $this->Tag->id = null;
+ $ret = $this->Tag->save(array (
+ 'tag_text' => $text,
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ ));
+
+ $this->assertTrue($ret, "inserted tag '$text'");
+
+ return $this->Tag->getLastInsertId();
+
+ }
+
+
+
+ function setUp() {
+ $yem = "great";
+ $this->assertEqual($yem, "great");
+ $arrayTagData = array (
+ 'tag_text' => 'yem',
+ 'blacklisted' => 0,
+ 'created' => date('Y-m-d h:i:s', time())
+ );
+
+ $this->Tag->save($arrayTagData);
+ $this->tagId = $this->Tag->getLastInsertId();
+
+ }
+
+
+ function tearDown() {
+ $this->Addon->execute('delete from users_tags_addons');
+ $this->Addon->execute('delete from tag_stat');
+ $this->Addon->execute('delete from tags');
+
+ }
+
+
+ function testInsertAndFindTag() {
+ // now get the latest tag
+ $dbTag = $this->Tag->findById($this->tagId);
+
+ $this->assertEqual($dbTag['Tag']['id'], $this->tagId);
+ $this->assertEqual($dbTag['Tag']['tag_text'], "yem");
+ $this->assertEqual($dbTag['Tag']['blacklisted'], 0);
+ }
+
+
+ function cleanupAllTestData() {
+ $this->Addon->execute('delete from users_tags_addons');
+ $this->Addon->execute('delete from tag_stat');
+ $this->Addon->execute('delete from tags');
+ }
+
+ function testGetDistinctTagsForAddons() {
+ $tag1Id = $this->addTag('tag1');
+ $tag2Id = $this->addTag('tag2');
+ $tag3Id = $this->addTag('tag3');
+ $tag4Id = $this->addTag('tag4');
+ $tag5Id = $this->addTag('tag5');
+ $tag6Id = $this->addTag('tag6');
+ $tag7Id = $this->addTag('tag7');
+ $tag8Id = $this->addTag('tag8');
+
+ $this->Addon->addTag(1, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(1, $tag2Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tag2Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(3, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(3, $tag2Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(4, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(4, $tag4Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(5, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(6, $tag1Id, 9); // addon+id, tag_id, user_id
+
+ $results = $this->Tag->getDistinctTagsForAddons(array(1,2,3,4));
+ $this->assertTrue(count($results) == 3, "3 unique tags found");
+ //print_r($results);
+
+ $tagIds = array($tag1Id, $tag2Id, $tag4Id);
+ foreach( $results as $result) {
+ $tagId = $result['Tag']['id'];
+ $this->assertTrue(in_array($tagId, $tagIds), $tagId . " found");
+ }
+
+
+ // cleanup
+ $this->cleanupAllTestData();
+
+ }
+
+ function testBlacklistAndUnblacklist() {
+ $tag1Id = $this->addTag('tag1');
+ $this->Addon->addTag(1, $tag1Id, 9); // addon+id, tag_id, user_id
+ $this->Addon->addTag(2, $tag1Id, 9); // addon+id, tag_id, user_id
+
+ $this->Addon->Tag->blacklistTag($tag1Id);
+
+ $dbTag = $this->Addon->Tag->findById($tag1Id);
+ $this->assertTrue($dbTag['Tag']['blacklisted'] == "1", "tag is blacklisted");
+
+ $dbUserTagAddons = $this->UserTagAddon->findByTagId($tag1Id);
+ $this->assertTrue($dbUserTagAddons == null, "tag removed from all addons");
+
+ $dbTagStat = $this->Tag->TagStat->findByTagId($tag1Id);
+ $this->assertTrue($dbTagStat['TagStat']['num_addons'] == 0, "tag stat is 0");
+
+ // now unblacklist
+ $this->Addon->Tag->unblacklistTag($tag1Id);
+ $dbTag = $this->Addon->Tag->findById($tag1Id);
+ $this->assertTrue($dbTag['Tag']['blacklisted'] == "0", "tag is UNblacklisted");
+
+ $this->cleanupAllTestData();
+ }
+}
+?>
diff --git a/site/app/tests/models/translation_model.test.php b/site/app/tests/models/translation_model.test.php
index ebb3c77..376f30b 100644
--- a/site/app/tests/models/translation_model.test.php
+++ b/site/app/tests/models/translation_model.test.php
@@ -53,7 +53,7 @@ class TranslationTest extends UnitTestCase {
function setUp()
{
- $this->Tag =& new Tag();
+ $this->Category =& new Category();
}
/**
@@ -62,7 +62,7 @@ class TranslationTest extends UnitTestCase {
function testAfterFind()
{
- $_all_data = $this->Tag->findAll();
+ $_all_data = $this->Category->findAll();
// General check - make sure we got data back
$this->assertEqual($_all_data[0]['Translation']['name']['string'], 'Developer Tools');
diff --git a/site/app/tests/views/addons/display.test.php b/site/app/tests/views/addons/display.test.php
index a0eaa10..b9cf0f6 100644
--- a/site/app/tests/views/addons/display.test.php
+++ b/site/app/tests/views/addons/display.test.php
@@ -42,7 +42,7 @@ class AddonTest extends WebTestHelper {
function AddonTest() {
$this->WebTestCase("Views->Addons->Display Tests");
loadModel('Addon');
- loadModel('Tag');
+ loadModel('Category');
loadModel('Version');
}
@@ -52,22 +52,22 @@ class AddonTest extends WebTestHelper {
$model =& new Addon();
$model->caching = false;
- $tagModel =& new Tag();
- $tagModel->caching = false;
+ $categoryModel =& new Category();
+ $categoryModel->caching = false;
$versionModel =& new Version();
$versionModel->caching = false;
$this->data = $model->find("Addon.id=$this->id", null , null , 2);
$this->data['Version'] = $versionModel->findAll("Version.addon_id=$this->id", null, "Version.created DESC", 0);
- //get tag l10n data
- foreach ($this->data['Tag'] as $tagkey => $tagvalue) {
- if ($tagkey == 0)
- $related_tag_query = "Tag.id='${tagvalue['id']}'";
+ //get category l10n data
+ foreach ($this->data['Category'] as $categorykey => $categoryvalue) {
+ if ($categorykey == 0)
+ $related_category_query = "Category.id='${categoryvalue['id']}'";
else
- $related_tag_query = $related_tag_query . " OR Tag.id ='${tagvalue['id']}'";
+ $related_category_query = $related_category_query . " OR Category.id ='${categoryvalue['id']}'";
}
- $this->tagData = $tagModel->findAll($related_tag_query);
+ $this->categoryData = $categoryModel->findAll($related_category_query);
$this->getAction("/addon/" . $this->id);
@@ -100,9 +100,9 @@ class AddonTest extends WebTestHelper {
//$this->wantedPattern = "#<span>\(" . $this->data['Version'][0]['File'][0]['size'] . "KB\)</span>#";
//$this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
- // tags
- foreach ($this->tagData as $tag) {
- $this->wantedPattern = "@<li><a href=\"[^\"]+\"( )*>" . $tag['Translation']['name']['string'] . "</a></li>@";
+ // categories
+ foreach ($this->categoryData as $category) {
+ $this->wantedPattern = "@<li><a href=\"[^\"]+\"( )*>" . $category['Translation']['name']['string'] . "</a></li>@";
$this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
}
// are reviews displayed?
diff --git a/site/app/tests/views/developers/edit.test.php b/site/app/tests/views/developers/edit.test.php
index bded1f3..7aa09a6 100644
--- a/site/app/tests/views/developers/edit.test.php
+++ b/site/app/tests/views/developers/edit.test.php
@@ -74,7 +74,7 @@ class DevelopersEditTest extends WebTestHelper {
$this->assertTitle('Developer Tools :: Firefox Add-ons');
//Check fields
- $this->assertWantedPattern('/\<option value="12" +selected="selected"\>Organizer\<\/option\>/', 'Tag selected');
+ $this->assertWantedPattern('/\<option value="12" +selected="selected"\>Organizer\<\/option\>/', 'Category selected');
$this->assertText($this->data['User'][0]['firstname'].' '.$this->data['User'][0]['lastname'].' ['.$this->data['User'][0]['email'].']', 'Author populated');
diff --git a/site/app/tests/views/helpers/addons_html.test.php b/site/app/tests/views/helpers/addons_html.test.php
index beabf0b..258a84e 100644
--- a/site/app/tests/views/helpers/addons_html.test.php
+++ b/site/app/tests/views/helpers/addons_html.test.php
@@ -105,7 +105,7 @@ class AddonsHtmlHelperTest extends UnitTestCase {
}
/**
- * Tests that an addon that has the addons_tags.feature = 1 is shown as featured
+ * Tests that an addon that has the addons_categories.feature = 1 is shown as featured
*/
function testRecommendedFlag() {
$addon = $this->Addon->getAddon(4021, array('all_tags'));
diff --git a/site/app/views/addons/browse.thtml b/site/app/views/addons/browse.thtml
index 7c5f80f..2c9574a 100644
--- a/site/app/views/addons/browse.thtml
+++ b/site/app/views/addons/browse.thtml
@@ -47,9 +47,9 @@ $this->layout = 'amo2009';
<div class="stand-alone-options">
<?=$this->renderElement('amo2009/categories')?>
<?php
- if (!empty($type) && array_key_exists('Tag', $this_tag))
+ if (!empty($type) && array_key_exists('Category', $this_category))
echo $this->renderElement('amo2009/search', array('category' =>
- array($type, $this_tag['Tag']['id'])));
+ array($type, $this_category['Category']['id'])));
else
echo $this->renderElement('amo2009/search');
?>
diff --git a/site/app/views/addons/browse_thumbs.thtml b/site/app/views/addons/browse_thumbs.thtml
index a5c029e..112b565 100644
--- a/site/app/views/addons/browse_thumbs.thtml
+++ b/site/app/views/addons/browse_thumbs.thtml
@@ -141,6 +141,37 @@ $this->layout = 'amo2009';
?>
</ul>
+ <br style="clear:both" />
+
+ <?=$this->renderElement('pagination', array('countstring' =>
+ sprintf(ngettext('addon_list_category_totalcount',
+ 'addon_list_category_totalcount', $paging['total']), $paging['total'])));?>
+
+ </div> <!-- #thumb-browser -->
+
+
+ </div><!-- /#content-main -->
+
+ <div id="thumb-subcategories">
+ <ul class="subcategories">
+ <li<?= ($this_category == FALSE) ? ' class="selected"' : '' ?>><?=$html->link(
+ 'All ('.$all_total.')',
+ "/browse/type:{$type}/cat:all?sort={$sort_by}"
+ )?></li>
+ <?php foreach ($subcats as $subcat): ?>
+ <?php
+ $params = 'sort=' . $sort_by;
+ if ($show_exp)
+ $params .= '&exp=on';
+ if ($show_limit)
+ $params .= '&show=' . $show_limit;
+ ?>
+ <li<?= ($this_category['Category']['id'] == $subcat['Category']['id']) ? ' class="selected"' : '' ?>><?=$html->link(
+ $subcat['Translation']['name']['string'] . ' (' . (isset($subcat_totals[$subcat['Category']['id']]) ? $subcat_totals[$subcat['Category']['id']] : 0) . ')',
+ "/browse/type:{$subcat['Category']['addontype_id']}/cat:{$subcat['Category']['id']}?{$params}"
+ )?></li>
+ <?php endforeach; ?>
+ </ul>
</div>
<?=$this->renderElement('amo2009/pagination');?>
diff --git a/site/app/views/addons/category_landing.thtml b/site/app/views/addons/category_landing.thtml
index db0764c..55f6952 100644
--- a/site/app/views/addons/category_landing.thtml
+++ b/site/app/views/addons/category_landing.thtml
@@ -41,8 +41,8 @@
$this->viewVars['bodyclass'] = 'inverse category_landing';
$this->layout = 'amo2009';
-$curr_tag_name = $this_tag['Translation']['name']['string'];
-$curr_tag_desc = $this_tag['Translation']['description']['string'];
+$curr_category_name = $this_category['Translation']['name']['string'];
+$curr_category_desc = $this_category['Translation']['description']['string'];
$nameLimit = 40;
$summaryLimit = 70;
@@ -54,7 +54,7 @@ $summaryLimit = 70;
<div class="primary" role="main">
- <h2><?php echo $curr_tag_name ?></h2>
+ <h2><?php echo $curr_category_name ?></h2>
<div id="featured_addons" class="clearfix">
<ul>
@@ -98,8 +98,8 @@ $summaryLimit = 70;
$icon = '';
// prepare categories
- if (!empty($addon['Tag'])) {
- $categories = $this->renderElement('addon_categories', array('tags' => $addon['Tag']));
+ if (!empty($addon['Category'])) {
+ $categories = $this->renderElement('addon_categories', array('categories' => $addon['Category']));
} else
$categories = '';
diff --git a/site/app/views/addons/display.thtml b/site/app/views/addons/display.thtml
index 43d7238..4a6b76b 100644
--- a/site/app/views/addons/display.thtml
+++ b/site/app/views/addons/display.thtml
@@ -116,6 +116,9 @@ if (!empty($coll_addon_added)) {
<?=nl2br($addon['Translation']['summary']['string'])?>
</p>
+ <h4 class="hidden"><?=_('addons_display_categories')?></h4>
+ <?=$this->renderElement('addon_categories', array('categories' => $relatedCategories)); ?>
+
<?php
if ($hasversion):
if (array_key_exists('collection_id', $_GET) && $this->controller->Collection->isValidUUID($_GET['collection_id'])) {
@@ -392,9 +395,9 @@ if (!empty($coll_addon_added)) {
<div class="highlight">
<?php
- if (is_array($relatedTags)) {
- foreach ($relatedTags as $tag) {
- echo $html->link(sprintf(_('addons_display_see_all_addons'),$tag['Translation']['name']['string']), '/browse/' . "type:" . $tag['Tag']['addontype_id'] . '/' . "cat:" . $tag['Tag']['id'], array('class' => 'more-info')) . "\n";
+ if (is_array($relatedCategories)) {
+ foreach ($relatedCategories as $category) {
+ echo $html->link(sprintf(_('addons_display_see_all_addons'),$category['Translation']['name']['string']), '/browse/' . "type:" . $category['Category']['addontype_id'] . '/' . "cat:" . $category['Category']['id'], array('class'=>'more-info')) . "\n";
}
}
?>
@@ -423,6 +426,23 @@ if (!empty($coll_addon_added)) {
<?php endif; ?>
</div>
+<div class="highlight">
+<h3>Tags</h3>
+<div id='tags'><?=$this->renderElement('addon_tags',array('userTags'=>$userTags, 'developerTags'=>$developerTags,'addon_id'=>$addon_id, 'origin'=>'users')); ?></div>
+
+<? if ($loggedIn) {
+ ?>
+ <a href="" id="addatag">+ Add a tag</a>
+ <div class="addtagform ">
+ <form id='#tagForm' action="/tags/add/">
+ <input type="text" id='newTag' name="newTag" method="POST">
+ <input type="hidden" name="addonid" id="addtagformaddonid" value="<?=$addon['Addon']['id']?>"/>
+ <button id="addtagbutton">Add</button>
+ </form>
+ </div>
+<? } else { echo $html->link(_('header_navlink_login'), $html->login_url()) . " to add tags."; } ?>
+
+</div>
<!-- /#more-addons-->
<div class="highlight collections-add prose">
diff --git a/site/app/views/addons/fortag.thtml b/site/app/views/addons/fortag.thtml
new file mode 100644
index 0000000..e59592b
--- /dev/null
+++ b/site/app/views/addons/fortag.thtml
@@ -0,0 +1,9 @@
+<h2><?=count($addons)?> Addons found for tag <b><i><?=$tag_text?></i></b></h2>
+
+<?
+ foreach ($addons as $var => $val) {
+ echo $this->renderElement('amo2009/homepage_addon', array('addon' => $val));
+ }
+
+
+?> \ No newline at end of file
diff --git a/site/app/views/addons/rss/categories.thtml b/site/app/views/addons/rss/categories.thtml
index 718592f..f5b5287 100644
--- a/site/app/views/addons/rss/categories.thtml
+++ b/site/app/views/addons/rss/categories.thtml
@@ -36,14 +36,14 @@
*
* ***** END LICENSE BLOCK ***** */
-foreach ($tagList as $cat) {
- $caturl = SITE_URL.$html->url("/browse/type:{$type}/cat:{$cat['Tag']['id']}");
+foreach ($categoryList as $cat) {
+ $caturl = SITE_URL.$html->url("/browse/type:{$type}/cat:{$cat['Category']['id']}");
echo $this->renderElement('rss_listitem', array(
'title' => $cat['Translation']['name']['string'],
'url' => $caturl,
'description' =>$cat['Translation']['description']['string'],
'author' => '',
- 'pubDate' => $time->toRss($cat['Tag']['created']),
+ 'pubDate' => $time->toRss($cat['Category']['created']),
'permalink' => $caturl
));
}
diff --git a/site/app/views/addons/searchengines.thtml b/site/app/views/addons/searchengines.thtml
index 920e3a1..419f60a 100644
--- a/site/app/views/addons/searchengines.thtml
+++ b/site/app/views/addons/searchengines.thtml
@@ -71,19 +71,19 @@ $this->layout = 'amo2009';
<h3 class="compact"><?=$html->link(_('search_landing_browse_search_engines'), "/browse/type:".ADDON_SEARCH."/cat:all?sort=name", array('class'=>'view'))?></h3>
- <ul class="highlight">
- <li><?=$html->link(_('search_landing_all_search_engines'),
- "/browse/type:".ADDON_SEARCH."/cat:all?sort=name", array('class' => 'category'))?></li>
- <?php foreach ($subcats as $subcat): ?>
- <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'],
- "/browse/type:{$subcat['Tag']['addontype_id']}/cat:{$subcat['Tag']['id']}?sort=name", array('class' => 'category'))?></li>
- <?php endforeach; ?>
- </ul>
+ <div class="more-addons">
+ <ul class="highlight">
+ <li><?=$html->link(_('search_landing_all_search_engines'), "/browse/type:".ADDON_SEARCH."/cat:all?sort=name", array('class' => 'category'))?></li>
+ <?php foreach ($subcats as $subcat): ?>
+ <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'], "/browse/type:{$subcat['Category']['addontype_id']}/cat:{$subcat['Category']['id']}?sort=name", array('class' => 'category'))?></li>
+ <?php endforeach; ?>
+ </ul>
+ </div>
<h3 class="clear"><?=___('addons_searchengines_additional_resources')?></h3>
- <div class="article prose compact">
+ <div class="article prose compact more-addons">
<ul>
- <li><?=$html->link(sprintf(_('category_extra_see_all'), $this_tag['Translation']['name']['string']), "/browse/type:{$this_tag['Tag']['addontype_id']}/cat:{$this_tag['Tag']['id']}?sort=name", array('class'=>'view'))?></li>
+ <li><?=$html->link(sprintf(_('category_extra_see_all'), $this_category['Translation']['name']['string']), "/browse/type:{$this_category['Category']['addontype_id']}/cat:{$this_category['Category']['id']}?sort=name", array('class'=>'view'))?></li>
<li><?=sprintf(___('addons_searchengines_more'), $html->link(___('addons_searchengines_mycroft_link'), 'http://mycroft.mozdev.org/'))?></li>
<li><?=sprintf(___('addons_searchengines_learn_howto'),
$html->link(___('addons_searchengines_makeyourown_link'), 'http://developer.mozilla.org'.___('addons_searchengines_makeyourown_href')),
diff --git a/site/app/views/addons/themes_landing.thtml b/site/app/views/addons/themes_landing.thtml
index f6af812..945b559 100644
--- a/site/app/views/addons/themes_landing.thtml
+++ b/site/app/views/addons/themes_landing.thtml
@@ -63,13 +63,13 @@ $this->layout = 'amo2009';
<?php endif; /* !empty($featureAddons) */ ?>
</div><!-- /.primary -->
-<div class="secondary" role="navigation">
+<div class="secondary more-addons" role="navigation">
<h3 class="compact"><?=$html->link(_('themes_landing_browse_themes'), "/browse/type:".ADDON_THEME."/cat:all?sort=name", array('class'=>'view'))?></h3>
<ul class="highlight">
<li><?=$html->link(_('themes_landing_all_themes'), "/browse/type:".ADDON_THEME."/cat:all?sort=name")?></li>
<?php foreach ($subcats as $subcat): ?>
- <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'], "/browse/type:{$subcat['Tag']['addontype_id']}/cat:{$subcat['Tag']['id']}?sort=name", array('class' => 'category'))?></li>
+ <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'], "/browse/type:{$subcat['Category']['addontype_id']}/cat:{$subcat['Category']['id']}?sort=name", array('class' => 'category'))?></li>
<?php endforeach; ?>
</ul>
</div><!-- /.secondary -->
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/admin/categories.thtml
index c95a1cf..9004912 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/admin/categories.thtml
@@ -39,28 +39,21 @@
<?=$this->renderElement('developers/adminmenu');?>
<div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
+ <h3>Category Manager</h3>
+ <?php
+ if (!empty($categories)) {
+ foreach ($categories as $category) {
+ echo '<div class="groupItem">';
+ echo '<h3>'.$category['Translation']['name']['string'].'</h3>';
+ echo $category['Translation']['description']['string'];
+ echo '<br>Application: '.$category['application'];
+ echo ' | Add-on type: '.$category['addontype'];
+ echo ' | Add-on Count: '.$category['count'];
+ echo ' | '.$html->link('Edit Category', '/admin/categories/edit/'.$category['Category']['id']);
+ echo '</div>';
+ }
}
- echo $html->formTag('/admin/tags/create');
+ echo $html->link('Create Category', '/admin/categories/create');
?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
</div>
</div>
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/admin/categories_create.thtml
index c95a1cf..71da2d0 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/admin/categories_create.thtml
@@ -44,16 +44,16 @@
if (!empty($errors['main'])) {
echo '<div class="error">'.$errors['main'].'</div>';
}
- echo $html->formTag('/admin/tags/create');
+ echo $html->formTag('/admin/categories/create');
?>
<div id="developersForm">
<div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
+ <label for="CategoryApplicationId">Application</label>
+ <?=$html->selectTag('Category/application_id', $applications, null, null, null, false)?>
</div>
<div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
+ <label for="CategoryAddontypeId">Add-on Type</label>
+ <?=$html->selectTag('Category/addontype_id', $addontypes, null, null, null, false)?>
</div>
<?=$this->renderElement('developers/localebox')?>
<div class="buttonBox">
@@ -61,6 +61,6 @@
</div>
</div>
</form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
+ <?=$html->link('Back to Category Manager', '/admin/categories')?>
</div>
</div>
diff --git a/site/app/views/admin/tags_edit.thtml b/site/app/views/admin/categories_edit.thtml
index e252282..a4582c3 100644
--- a/site/app/views/admin/tags_edit.thtml
+++ b/site/app/views/admin/categories_edit.thtml
@@ -39,25 +39,25 @@
<?=$this->renderElement('developers/adminmenu');?>
<div id="content-main">
- <h3>Edit Category '<?=$tag['Translation']['name']['string']?>'</h3>
+ <h3>Edit Category '<?=$category['Translation']['name']['string']?>'</h3>
<?php
if (!empty($errors['main'])) {
echo '<div class="error">'.$errors['main'].'</div>';
}
- echo $html->formTag('/admin/tags/edit/'.$tag['Tag']['id']);
+ echo $html->formTag('/admin/categories/edit/'.$category['Category']['id']);
?>
<div id="developersForm">
<div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, $tag['Tag']['application_id'], null, null, false)?>
+ <label for="categoryApplicationId">Application</label>
+ <?=$html->selectTag('Category/application_id', $applications, $category['Category']['application_id'], null, null, false)?>
</div>
<div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, $tag['Tag']['addontype_id'], null, null, false)?>
+ <label for="CategoryAddontypeId">Add-on Type</label>
+ <?=$html->selectTag('Category/addontype_id', $addontypes, $category['Category']['addontype_id'], null, null, false)?>
</div>
<div>
- <label for="TagWeightId">Category Weight (<small>sort-order</small>)</label>
- <?=$html->input('Tag/weight', array('value' => $tag['Tag']['weight']))?>
+ <label for="CategoryWeightId">Category Weight (<small>sort-order</small>)</label>
+ <?=$html->input('Category/weight', array('value' => $category['Category']['weight']))?>
</div>
<?=$this->renderElement('developers/localebox')?>
<div class="buttonBox">
@@ -66,6 +66,6 @@
</div>
</div>
</form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
+ <?=$html->link('Back to Category Manager', '/admin/categories')?>
</div>
</div>
diff --git a/site/app/views/admin/lists.thtml b/site/app/views/admin/lists.thtml
index b6abd8b..48aa12d 100644
--- a/site/app/views/admin/lists.thtml
+++ b/site/app/views/admin/lists.thtml
@@ -41,10 +41,12 @@
<div id="content-main">
<h3>List Manager</h3>
<ul>
- <li><h2><?=$html->link('Categories', '/admin/tags')?></h2></li>
+ <li><h2><?=$html->link('Categories', '/admin/categories')?></h2></li>
<li><h2><?=$html->link("Collection Features' Titles and Taglines", '/admin/collections/promoboxstructure')?></h2></li>
<li><h2><?=$html->link('Platforms', '/admin/platforms')?></h2></li>
<li><h2><?=$html->link('Responses', '/admin/responses')?></h2></li>
+ <li><h2><?=$html->link('Tags', '/admin/tags')?></h2></li>
+
</ul>
</div>
</div>
diff --git a/site/app/views/admin/logs.thtml b/site/app/views/admin/logs.thtml
index 7cf05f4..5e64457 100644
--- a/site/app/views/admin/logs.thtml
+++ b/site/app/views/admin/logs.thtml
@@ -63,9 +63,9 @@
<option>admin:response_create</option>
<option>admin:response_delete</option>
<option>admin:response_edit</option>
- <option>admin:tag_create</option>
- <option>admin:tag_delete</option>
- <option>admin:tag_edit</option>
+ <option>admin:category_create</option>
+ <option>admin:category_delete</option>
+ <option>admin:category_edit</option>
<option>admin:user_edit</option>
<option>editor:*</option>
<option>editor:review_approve</option>
@@ -74,7 +74,7 @@
<option>l10n:update_addontypes</option>
<option>l10n:update_applications</option>
<option>l10n:update_platforms</option>
- <option>l10n:update_tags</option>
+ <option>l10n:update_categories</option>
<option>security:*</option>
<option>security:modify_locked_group</option>
<option>security:modify_other_locale</option>
diff --git a/site/app/views/admin/tags.thtml b/site/app/views/admin/tags.thtml
index 5aa620c..41709bf 100644
--- a/site/app/views/admin/tags.thtml
+++ b/site/app/views/admin/tags.thtml
@@ -39,21 +39,50 @@
<?=$this->renderElement('developers/adminmenu');?>
<div id="content-main">
- <h3>Category Manager</h3>
+ <h3>Tag Manager</h3>
+ <table width="100%">
+ <?
+ $pagination->setPaging($paging); // Initialize the pagination variables
+ $th = array (
+ $pagination->sortBy('tag_text','Tag','Tag'),
+ $pagination->sortBy('created','Created','Tag'),
+ $pagination->sortBy('blacklisted'),
+ $pagination->sortBy('num_addons','Popularity','TagStat'),
+ ); // Generate the pagination sort links
+ echo $html->tableHeaders($th); // Create the table headers with sort links if desired
+ // <tr><th>Tag</th><th>Created</th><th>Blacklisted</th><th>Count</th></tr>
+
+
+ ?>
<?php
if (!empty($tags)) {
foreach ($tags as $tag) {
- echo '<div class="groupItem">';
- echo '<h3>'.$tag['Translation']['name']['string'].'</h3>';
- echo $tag['Translation']['description']['string'];
- echo '<br>Application: '.$tag['application'];
- echo ' | Add-on type: '.$tag['addontype'];
- echo ' | Add-on Count: '.$tag['count'];
- echo ' | '.$html->link('Edit Category', '/admin/tags/edit/'.$tag['Tag']['id']);
- echo '</div>';
+ echo '<tr>';
+ echo '<td><span>'.$html->link($tag['Tag']['tag_text'], '/tag/'.$tag['Tag']['tag_text']).'</span></td>';
+ echo '<td>'.$tag['Tag']['created'] . '</td>';
+ echo '<td>'.$tag['Tag']['blacklisted'] . '</td>';
+ echo '<td>'.$tag['TagStat']['num_addons'] . '</td>';
+ echo '<td>';
+ if ($tag['Tag']['blacklisted']) {
+ echo $html->link('Un-blacklist', '/admin/tags/unblacklist/'.$tag['Tag']['id']);
+ } else {
+ echo $html->link('Blacklist', '/admin/tags/blacklist/'.$tag['Tag']['id']);
+ }
+ echo '</td>';
+ echo '</tr>';
+
}
}
- echo $html->link('Create Category', '/admin/tags/create');
+ ?></table><?
+ echo $this->renderElement('pagination');
+
?>
+ <h3>Blacklist Tags</h3>
+ <div class="addtagform ">
+ <form action="/tags/addAndBlacklist/">
+ <input type="text" id='newTag' name="newTag" method="POST">
+ <button id="addtagbutton">Add</button>
+ </form>
+ </div>
</div>
</div>
diff --git a/site/app/views/api/collections_feed.thtml b/site/app/views/api/collections_feed.thtml
index 3e856ff..7a3704f 100644
--- a/site/app/views/api/collections_feed.thtml
+++ b/site/app/views/api/collections_feed.thtml
@@ -62,8 +62,8 @@ if (isset($error)) { ?>
<comments><?php echo $addon['collection_comments'] ?></comments>
</meta>
<categories>
- <?php foreach ($addon['tags'] as $tag): ?>
- <category id="<?php echo $tag['id'] ?>"><?php echo $tag['name'] ?></category>
+ <?php foreach ($addon['categories'] as $category): ?>
+ <category id="<?php echo $category['id'] ?>"><?php echo $category['name'] ?></category>
<?php endforeach ?>
</categories>
<name><?php echo $addon['name']; ?></name>
diff --git a/site/app/views/collections/ajax/addon_lookup.thtml b/site/app/views/collections/ajax/addon_lookup.thtml
index 80207ed..fe4e99b 100644
--- a/site/app/views/collections/ajax/addon_lookup.thtml
+++ b/site/app/views/collections/ajax/addon_lookup.thtml
@@ -38,6 +38,7 @@
header('Content-type: text/plain');
+define('NO_MICROTIME', true);
if (!empty($addons)) {
echo "[\n";
diff --git a/site/app/views/developers/addon_edit.thtml b/site/app/views/developers/addon_edit.thtml
index 5e0d147..07fdf87 100644
--- a/site/app/views/developers/addon_edit.thtml
+++ b/site/app/views/developers/addon_edit.thtml
@@ -47,6 +47,8 @@
<dd><?=___('devcp_edit_dd_manage_authors')?></dd>
<dt class="edit-categories"><?=$html->link(___('devcp_edit_dt_manage_categories'), "/developers/addon/edit/{$addon_id}/categories")?></dt>
<dd><?=___('devcp_edit_dd_manage_categories')?></dd>
+ <dt class="edit-tags"><?=$html->link(___('devcp_edit_dt_manage_tag'), "/developers/addon/edit/{$addon_id}/tags")?></dt>
+ <dd><?=___('devcp_edit_dd_manage_tags')?></dd>
<dt class="edit-descriptions"><?=$html->link(___('devcp_edit_dt_manage_descriptions'), "/developers/addon/edit/{$addon_id}/descriptions")?></dt>
<dd><?=___('devcp_edit_dd_manage_description')?></dd>
<dt class="edit-properties"><?=$html->link(___('devcp_edit_dt_manage_properties'), "/developers/addon/edit/{$addon_id}/properties")?></dt>
diff --git a/site/app/views/developers/addon_edit_categories.thtml b/site/app/views/developers/addon_edit_categories.thtml
index 4950629..1a2c8e7 100644
--- a/site/app/views/developers/addon_edit_categories.thtml
+++ b/site/app/views/developers/addon_edit_categories.thtml
@@ -50,41 +50,41 @@
<?=$this->renderElement('noscript')?>
<?=$this->renderElement('developers/rolecheck')?>
<?php
- if (!empty($sortedTags)) {
+ if (!empty($sortedCategories)) {
echo '<form id="addon-edit-categories-form" action="" method="post">';
echo $html->hiddenSession();
- foreach ($sortedTags as $application_id => $tags) {
- $otherSelected = !empty($otherTags[$application_id]) && in_array($otherTags[$application_id], $currentTags);
+ foreach ($sortedCategories as $application_id => $categories) {
+ $otherSelected = !empty($otherCategories[$application_id]) && in_array($otherCategories[$application_id], $currentCategories);
echo '<div class="edit-categories-box field graybox rounded spaced app-'.$application_id.'">';
echo '<h4 style="border-bottom: none;">'.$html->image('app-icons/'.strtolower($applications[$application_id]).'_small.png', array('alt' => $applications[$application_id]));
echo sprintf(___('devcp_edit_categories_header_application'), $applications[$application_id]).'</h4>';
- if (!empty($tags)) {
+ if (!empty($categories)) {
echo '<p>'.sprintf(___('devcp_edit_categories_select_application_categories'), $applications[$application_id]).':</p>';
echo '<table style="width: 100%;"><tr><td style="width: 50%;">';
for ($i = 1; $i <= 3; $i++) {
$selected = false;
echo '<label>'.sprintf(___('devcp_edit_categories_label_category_num'), $i).':&nbsp;';
- echo '<select name="data[Tag]['.$application_id.'][]"'.($otherSelected ? ' disabled="disabled"' : '').'>';
+ echo '<select name="data[Category]['.$application_id.'][]"'.($otherSelected ? ' disabled="disabled"' : '').'>';
echo '<option value="" style="color: gray;">'.___('devcp_edit_authors_option_empty').'</option>';
- foreach ($tags as $tag_id => $tag_name) {
- if ($otherTags[$application_id] == $tag_id)
+ foreach ($categories as $category_id => $category_name) {
+ if ($otherCategories[$application_id] == $category_id)
continue;
- echo '<option value="'.$tag_id.'"';
- if (in_array($tag_id, $currentTags) && !$selected) {
+ echo '<option value="'.$category_id.'"';
+ if (in_array($category_id, $currentCategories) && !$selected) {
echo ' selected="selected"';
- unset($currentTags[array_search($tag_id, $currentTags)]);
+ unset($currentCategories[array_search($category_id, $currentCategories)]);
$selected = true;
}
- echo ' onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$tag_name.'</strong><br />'.$html->entities($tagDescriptions[$tag_id])).'\');"';
- echo '>'.$html->entities($tag_name).'</option>'."\n";
+ echo ' onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$category_name.'</strong><br />'.$html->entities($categoryDescriptions[$category_id])).'\');"';
+ echo '>'.$html->entities($category_name).'</option>'."\n";
}
echo '</select></label>';
}
- if (!empty($otherTags[$application_id])) {
- echo '<label onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$sortedTags[$application_id][$otherTags[$application_id]].'</strong><br />'.___('devcp_edit_categories_other')).'\');">';
- echo '<input type="checkbox" name="data[Tag]['.$application_id.'][]" value="'.$otherTags[$application_id].'" onclick="addon_edit_categories.toggleDropdowns(this, '.$application_id.');"'.($otherSelected ? ' checked="checked"' : '').' />&nbsp;';
+ if (!empty($otherCategories[$application_id])) {
+ echo '<label onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$sortedCategories[$application_id][$otherCategories[$application_id]].'</strong><br />'.___('devcp_edit_categories_other')).'\');">';
+ echo '<input type="checkbox" name="data[Category]['.$application_id.'][]" value="'.$otherCategories[$application_id].'" onclick="addon_edit_categories.toggleDropdowns(this, '.$application_id.');"'.($otherSelected ? ' checked="checked"' : '').' />&nbsp;';
echo ___('devcp_edit_categories_does_not_fit');
echo '</label>';
}
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/developers/addon_edit_tags.thtml
index c95a1cf..f971d5d 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/developers/addon_edit_tags.thtml
@@ -15,11 +15,12 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2007
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -36,31 +37,29 @@
* ***** END LICENSE BLOCK ***** */
?>
<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
- <div id="content-main">
- <h3>Create Category</h3>
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
<?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
}
- echo $html->formTag('/admin/tags/create');
?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
+ <h2><?=___('devcp_edit_tags_header_manage')?></h2>
+ <?=$this->renderElement('developers/rolecheck')?>
+<div id='tags'><?=$this->renderElement('addon_tags',array('userTags'=>$userTags, 'developerTags'=>$developerTags,'addon_id'=>$addon_id, 'origin'=>'developers')); ?></div>
+ <a href="" id="addatag">+ Add a tag</a>
+ <div class="addtagform ">
+ <form action="/tags/add/">
+ <input type="text" id='newTag' name="newTag" method="POST">
+ <input type="hidden" name="addonid" id="addtagformaddonid" value="<?=$addon_data['Addon']['id']?>"/>
+ <input type="hidden" name="origin" id="origin" value="developers"/>
+
+ <button id="addtagbutton">Add</button>
+ </form>
+ </div>
+
+ <pre><? //print_r($addon_data); ?></pre>
+ </div>
</div>
diff --git a/site/app/views/editors/featured.thtml b/site/app/views/editors/featured.thtml
index 38348b0..aeef6ca 100644
--- a/site/app/views/editors/featured.thtml
+++ b/site/app/views/editors/featured.thtml
@@ -65,33 +65,33 @@
</tr>
<?php
$current_type = 0;
- foreach ($tags as $tag) :
+ foreach ($categories as $category) :
- if ($tag['Tag']['addontype_id'] != $current_type) {
- echo '<tr class="featureTypeHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']])).'"><th colspan="2">'.$html->image('developers/'.strtolower($applications[$tag['Tag']['application_id']]).'.png', array('title' => $applications[$tag['Tag']['application_id']])).' '.$addontypes[$tag['Tag']['addontype_id']].'</th></tr>';
- $current_type = $tag['Tag']['addontype_id'];
+ if ($category['Category']['addontype_id'] != $current_type) {
+ echo '<tr class="featureTypeHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$category['Category']['addontype_id']])).'"><th colspan="2">'.$html->image('developers/'.strtolower($applications[$category['Category']['application_id']]).'.png', array('title' => $applications[$category['Category']['application_id']])).' '.$addontypes[$category['Category']['addontype_id']].'</th></tr>';
+ $current_type = $category['Category']['addontype_id'];
}
- echo '<tr class="featureHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']])).'"><th colspan="2"><span lang="'.$tag['Translation']['name']['locale'].'">'.$tag['Translation']['name']['string'].'</span></th></tr>';
+ echo '<tr class="featureHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$category['Category']['addontype_id']])).'"><th colspan="2"><span lang="'.$category['Translation']['name']['locale'].'">'.$category['Translation']['name']['string'].'</span></th></tr>';
- $_class = preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']]));
- if (array_key_exists($tag['Tag']['id'], $addons_by_tag) && !empty($addons_by_tag[$tag['Tag']['id']])) {
+ $_class = preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$category['Category']['addontype_id']]));
+ if (array_key_exists($category['Category']['id'], $addons_by_category) && !empty($addons_by_category[$category['Category']['id']])) {
$zebra = 0;
- foreach ($addons_by_tag[$tag['Tag']['id']] as $addon):
+ foreach ($addons_by_category[$category['Category']['id']] as $addon):
$_evenodd = ($zebra++ % 2 == 0 ? ' even' : ' odd');
?>
- <tr class="<?=$_class.$_evenodd?>" id="feature-<?=$tag['Tag']['id']?>-<?=$addon['Addon']['id']?>">
+ <tr class="<?=$_class.$_evenodd?>" id="feature-<?=$category['Category']['id']?>-<?=$addon['Addon']['id']?>">
<td>
<?php
echo $html->formTag('/editors/featured/remove', 'post',
- array('id' => 'feature-remove-form-'.$tag['Tag']['id'].'-'.$addon['Addon']['id'],
- 'onsubmit' => 'removeFeature('.$tag['Tag']['id'].','.$addon['Addon']['id'].'); return false;'));
+ array('id' => 'feature-remove-form-'.$category['Category']['id'].'-'.$addon['Addon']['id'],
+ 'onsubmit' => 'removeFeature('.$category['Category']['id'].','.$addon['Addon']['id'].'); return false;'));
echo $html->submitImage('/developers/delete.png',
array('title'=>_('editors_featured_remove_feature'),
'alt' => _('editors_featured_remove_feature'),
'class' => 'featureremove',
- 'id' => 'delete-'.$tag['Tag']['id'].'-'.$addon['Addon']['id']));
- echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ 'id' => 'delete-'.$category['Category']['id'].'-'.$addon['Addon']['id']));
+ echo $html->hidden('Category/id', array('value' => $category['Category']['id']));
echo $html->hidden('Addon/id', array('value' => $addon['Addon']['id']));
echo '&nbsp;';
echo $html->link($addon['Translation']['name']['string'], '/addon/'.$addon['Addon']['id']);
@@ -100,11 +100,11 @@
</td>
<td>
<?php
- echo $html->formTag('/editors/featured/edit', 'post', array('id' => 'feature-edit-form-'.$tag['Tag']['id'].'-'.$addon['Addon']['id'], 'onsubmit' => 'editFeatureSubmit('.$tag['Tag']['id'].','.$addon['Addon']['id'].'); return false;'));
- echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ echo $html->formTag('/editors/featured/edit', 'post', array('id' => 'feature-edit-form-'.$category['Category']['id'].'-'.$addon['Addon']['id'], 'onsubmit' => 'editFeatureSubmit('.$category['Category']['id'].','.$addon['Addon']['id'].'); return false;'));
+ echo $html->hidden('Category/id', array('value' => $category['Category']['id']));
echo $html->hidden('Addon/id', array('value' => $addon['Addon']['id']));
- echo $html->input('AddonTag/feature_locales', array('id' => "edit-addon-locales-{$tag['Tag']['id']}-{$addon['Addon']['id']}", 'size' => 40, 'value' => $addon['AddonTag'][0]['feature_locales']));
- echo $html->submit(_('editors_featured_edit_feature_submit'), array('id' => 'edit-feature-submit-'.$tag['Tag']['id'].'-'.$addon['Addon']['id']));
+ echo $html->input('AddonCategory/feature_locales', array('id' => "edit-addon-locales-{$category['Category']['id']}-{$addon['Addon']['id']}", 'size' => 40, 'value' => $addon['AddonCategory'][0]['feature_locales']));
+ echo $html->submit(_('editors_featured_edit_feature_submit'), array('id' => 'edit-feature-submit-'.$category['Category']['id'].'-'.$addon['Addon']['id']));
?>
</form>
</td>
@@ -113,19 +113,19 @@
endforeach;
}
- echo '<tr class="'.$_class.' even" id="feature-add-tr-form-'.$tag['Tag']['id'].'"><td>';
- echo $html->formTag('/editors/featured/add', 'post', array('id' => 'feature-add-form-'.$tag['Tag']['id'], 'onsubmit' => 'addFeatureSubmit('.$tag['Tag']['id'].'); return false;'));
- echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ echo '<tr class="'.$_class.' even" id="feature-add-tr-form-'.$category['Category']['id'].'"><td>';
+ echo $html->formTag('/editors/featured/add', 'post', array('id' => 'feature-add-form-'.$category['Category']['id'], 'onsubmit' => 'addFeatureSubmit('.$category['Category']['id'].'); return false;'));
+ echo $html->hidden('Category/id', array('value' => $category['Category']['id']));
echo $html->submitImage('developers/add.png',
array('title' => _('editors_featured_add_feature'),
'alt' => _('editors_featured_add_feature'),
'class' => 'featureadd',
- 'id' => 'add-'.$tag['Tag']['id'],
+ 'id' => 'add-'.$category['Category']['id'],
)).'&nbsp;';
- echo '<input type="text" name="data[Addon][id]" id="new-addon-id-'.$tag['Tag']['id'].'" onfocus="prepAutocomplete('.$tag['Tag']['id'].');" size="40" />';
- echo '<noscript>'.$html->submit(_('editors_featured_add_feature_submit'), array('id' => 'new-feature-submit-'.$tag['Tag']['id'])).'</noscript>';
+ echo '<input type="text" name="data[Addon][id]" id="new-addon-id-'.$category['Category']['id'].'" onfocus="prepAutocomplete('.$category['Category']['id'].');" size="40" />';
+ echo '<noscript>'.$html->submit(_('editors_featured_add_feature_submit'), array('id' => 'new-feature-submit-'.$category['Category']['id'])).'</noscript>';
echo '</form></td>';
- echo '<td><span id="edit-feature-message-'.$tag['Tag']['id'].'"></span></td></tr>'; // use the extra space for messages
+ echo '<td><span id="edit-feature-message-'.$category['Category']['id'].'"></span></td></tr>'; // use the extra space for messages
endforeach;
?>
diff --git a/site/app/views/editors/review.thtml b/site/app/views/editors/review.thtml
index f3cb36f..8a28497 100644
--- a/site/app/views/editors/review.thtml
+++ b/site/app/views/editors/review.thtml
@@ -79,9 +79,9 @@
<span class="sectionTitle"><?=_('editors_review_header_categories')?></span>
<ul id="categorylist">
<?php
- if (!empty($addon['Tags'])) {
- foreach ($addon['Tags'] as $tag) {
- echo '<li '.$tag['Translation']['name']['locale_html'].'>'.$tag['Translation']['name']['string'].'</li>';
+ if (!empty($addon['Categories'])) {
+ foreach ($addon['Categories'] as $category) {
+ echo '<li '.$category['Translation']['name']['locale_html'].'>'.$category['Translation']['name']['string'].'</li>';
}
}
?>
diff --git a/site/app/views/elements/addon_categories.thtml b/site/app/views/elements/addon_categories.thtml
index 96d0e2b..cbad9e6 100644
--- a/site/app/views/elements/addon_categories.thtml
+++ b/site/app/views/elements/addon_categories.thtml
@@ -39,14 +39,14 @@
/**
* This element uses the following local variables:
- * - $tags (a Tag model-style result set)
+ * - $categories (a Category model-style result set)
*/
?>
<ul class="addon-cats">
<?php
// show top-level category for non-extension add-ons
-if (!empty($tags)) {
- switch ($tags[0]['Tag']['addontype_id']) {
+if (!empty($categories)) {
+ switch ($categories[0]['Category']['addontype_id']) {
case ADDON_DICT:
case ADDON_LPAPP:
$li = $html->link(___('nav_category_dicts_langpacks'), '/browse/type:'.ADDON_DICT);
@@ -62,14 +62,14 @@ if (!empty($tags)) {
// regular category list
$c = 0;
-foreach ($tags as $_tag) {
- if (0 == $c++)
+foreach ($categories as $_category) {
+ if (0 == $c++) {
echo '<li class="first">';
- else
+ } else {
echo '<li>';
- echo $html->link($_tag['Translation']['name']['string'],
- "/browse/type:{$_tag['Tag']['addontype_id']}/cat:{$_tag['Tag']['id']}")
- ."</li>\n";
+ }
+ echo $html->link($_category['Translation']['name']['string'],
+ "/browse/type:{$_category['Category']['addontype_id']}/cat:{$_category['Category']['id']}")."</li>\n";
}
?>
</ul>
diff --git a/site/app/views/elements/addon_discussionheader.thtml b/site/app/views/elements/addon_discussionheader.thtml
index 1dd3fae..3c8a365 100644
--- a/site/app/views/elements/addon_discussionheader.thtml
+++ b/site/app/views/elements/addon_discussionheader.thtml
@@ -42,7 +42,7 @@
/**
* This element uses the following local variables:
* - $addon (Addon model-style array, containing 'Addon' and
- * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * (optionally) 'Version', 'File', 'Category' sub-arrays)
* - $addonIconPath (optional)
* - $addonPreviewPath (optional)
*/
diff --git a/site/app/views/elements/addon_listitem.thtml b/site/app/views/elements/addon_listitem.thtml
index cd68b71..3927591 100644
--- a/site/app/views/elements/addon_listitem.thtml
+++ b/site/app/views/elements/addon_listitem.thtml
@@ -42,7 +42,7 @@
/**
* This element uses the following local variables:
* - $addon (Addon model-style array, containing 'Addon' and
- * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * (optionally) 'Version', 'File', 'Category' sub-arrays)
* - $addonIconPath (optional)
* - $addonPreviewPath (optional)
*/
@@ -78,8 +78,8 @@ else
$icon = '';
// prepare categories
-if (!empty($addon['Tag'])) {
- $categories = $this->renderElement('addon_categories', array('tags' => $addon['Tag']));
+if (!empty($addon['Category'])) {
+ $categories = $this->renderElement('addon_categories', array('categories' => $addon['Category']));
} else
$categories = '';
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/elements/addon_tags.thtml
index c95a1cf..f7f7803 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/elements/addon_tags.thtml
@@ -15,11 +15,12 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2007
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -33,34 +34,36 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
- * ***** END LICENSE BLOCK ***** */
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $tags (a tag model-style result set)
+ */
+
+
+
+
?>
-<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
- <div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
- }
- echo $html->formTag('/admin/tags/create');
- ?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
-</div>
+<ul class="addon-tags nojs" id="addonid-<?= $addon_id ?>">
+<?php
+// developer tag list
+foreach ($developerTags as $_tag) {
+ echo "<li id='taglink-".$_tag['Tag']['id']."' class='developertag'>".$html->link($_tag['Tag']['tag_text'], "/tag/".$_tag['Tag']['tag_text'], array('class'=>'tagitem'));
+ if (@$_tag['Tag']['OwnerOrDeveloper']==1) {
+ echo " <a href='/tags/remove/" . $_tag['UserTagAddon'][0]['addon_id'] . "/".$_tag['Tag']['id']."/$origin' id='remtag-". $_tag['Tag']['id']. "' class='removetag'>x</a></li>\n";
+ }
+}
+// user tag list
+foreach ($userTags as $_tag) {
+ echo "<li id='taglink-".$_tag['Tag']['id']."' class='usertag'>".$html->link($_tag['Tag']['tag_text'], "/tag/".$_tag['Tag']['tag_text'], array('class'=>'tagitem'));
+ if (@$_tag['Tag']['OwnerOrDeveloper']==1) {
+ echo " <a href='/tags/remove/" . $_tag['UserTagAddon'][0]['addon_id'] . "/".$_tag['Tag']['id']."' id='remtag-". $_tag['Tag']['id']. "' class='removetag'>x</a></li>\n";
+ }
+}
+?>
+</ul>
+<? //print_r($developerTags); ?>
+<? //print_r($userTags); ?> \ No newline at end of file
diff --git a/site/app/views/elements/amo2009/categories.thtml b/site/app/views/elements/amo2009/categories.thtml
index 9a4e06c..a67a59a 100644
--- a/site/app/views/elements/amo2009/categories.thtml
+++ b/site/app/views/elements/amo2009/categories.thtml
@@ -48,16 +48,16 @@
<ul id="categoriesdropdown">
<li>
<ul>
- <?php foreach ($AmoTags as $_tag): ?>
- <?php if (0===$_tag['cat'] && ADDON_PLUGIN!==$_tag['type']) continue ?>
+ <?php foreach ($AmoCategories as $_category): ?>
+ <?php if (0===$_category['cat'] && ADDON_PLUGIN!==$_category['type']) continue ?>
<?php
- $_url = "/browse/type:{$_tag['type']}".
- ($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
+ $_url = "/browse/type:{$_category['type']}".
+ ($_category['cat']!=0 ? "/cat:{$_category['cat']}" : '');
?>
<li>
- <?= $html->link($html->entities($_tag['name']), $_url) ?>
- <?php if (isset($_tag['count'])): ?>
- <span class="items"><?= $html->entities($_tag['count']) ?></span>
+ <?= $html->link($html->entities($_category['name']), $_url) ?>
+ <?php if (isset($_category['count'])): ?>
+ <span class="items"><?= $html->entities($_category['count']) ?></span>
<?php endif ?>
</li>
<?php endforeach ?>
@@ -68,19 +68,19 @@
<li>
<?= $html->link(___('addons_home_collections','Collections'), '/collections/') ?>
</li>
- <?php foreach ($AmoTags as $_tag): ?>
- <?php if (0!==$_tag['cat'] || ADDON_PLUGIN===$_tag['type']) continue ?>
+ <?php foreach ($AmoCategories as $_category): ?>
+ <?php if (0!==$_category['cat'] || ADDON_PLUGIN===$_category['type']) continue ?>
<?php
- if (ADDON_THEME === $_tag['type']) {
- $_url = "/browse/type:{$_tag['type']}/cat:all?sort=popular";
+ if (ADDON_THEME === $_category['type']) {
+ $_url = "/browse/type:{$_category['type']}/cat:all?sort=popular";
}
else {
- $_url = "/browse/type:{$_tag['type']}".
- ($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
+ $_url = "/browse/type:{$_category['type']}".
+ ($_category['cat']!=0 ? "/cat:{$_category['cat']}" : '');
}
?>
<li>
- <?= $html->link($html->entities($_tag['name']), $_url) ?>
+ <?= $html->link($html->entities($_category['name']), $_url) ?>
</li>
<?php endforeach ?>
</ul>
diff --git a/site/app/views/elements/amo2009/homepage_addon.thtml b/site/app/views/elements/amo2009/homepage_addon.thtml
index 6fc1f5a..652aede 100644
--- a/site/app/views/elements/amo2009/homepage_addon.thtml
+++ b/site/app/views/elements/amo2009/homepage_addon.thtml
@@ -48,7 +48,7 @@ $addonFiles = $addon['File'];
$addonEULA = $addon['Translation']['eula']['string'];
$addonStatus = $addon['Addon']['status'];
$addonAuthors = $addon['User'];
-$addonTags = $addon['Tag'];
+$addonCategories = $addon['Category'];
$addonWeeklyDownloads = $addon['Addon']['weeklydownloads'];
$allPlatforms = $platforms;
$compatible_apps = $addon['compatible_apps'];
@@ -123,8 +123,8 @@ if (isset($addonStatus) && in_array($addonStatus, $experimental_status)) {
array('class'=>'view', 'title'=>sprintf(_('feature_learnmore_about_addon'), $addonName)))?></p>
<?php endif; ?>
-<?php if(!empty($addonTags)): ?>
-<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonTags[0]['Tag']['id'])?>" class="view"><?=$addonTags[0]['Translation']['name']['string']?></a></p>
+<?php if(!empty($addonCategories)): ?>
+<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonCategories[0]['Category']['id'])?>" class="view"><?=$addonCategories[0]['Translation']['name']['string']?></a></p>
<?php endif; ?>
<?php endif ?>
diff --git a/site/app/views/elements/amo2009/results_addon.thtml b/site/app/views/elements/amo2009/results_addon.thtml
new file mode 100644
index 0000000..6488811
--- /dev/null
+++ b/site/app/views/elements/amo2009/results_addon.thtml
@@ -0,0 +1,135 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+$addonIconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+$addonThumbPath = $this->controller->Image->getHighlightedPreviewURL($addon['Addon']['id']);
+$addonName = $addon['Translation']['name']['string'];
+$addonSummary = $addon['Translation']['summary']['string'];
+$addonFiles = $addon['File'];
+$compatible_apps = $addon['compatible_apps'];
+$addonId = $addon['Addon']['id'];
+$addonStatus = $addon['Addon']['status'];
+$addonAuthors = $addon['User'];
+$addonCategories = $addon['Category'];
+$addonWeeklyDownloads = $addon['Addon']['weeklydownloads'];
+$allPlatforms = $platforms;
+$addonType = $addon['Addon']['addontype_id'];
+$addonRating = $addon['Addon']['averagerating'];
+$addonReviews = $addon['Addon']['totalreviews'];
+$addonVersionCreated = $addon['Version'][0]['created'];
+$addonDateChanged = $addon['Addon']['datestatuschanged'];
+
+// Bug 444817: limit length of addon descriptions in feature elements.
+$desc_limit = 250;
+if (mb_strlen($addonSummary) > $desc_limit) {
+ // If the addon summary exceeds the display limit, cut it off before the
+ // last space-delimited word in the string and add an ellipsis linking to
+ // the full detail page. Would use TextHelper::truncate() here, but need
+ // mb_* string functions.
+
+ // mb_substr is used twice here, because mb_strrpos doesn't support
+ // offset in PHP 5.1.6 - first chop down to char limit, then chop down
+ // to end of last space-delimited word.
+ $addonSummary = mb_substr($addonSummary, 0, $desc_limit);
+ $addonSummary = mb_substr($addonSummary, 0, mb_strrpos($addonSummary, ' ')) .
+ ' <a href="'.$html->url("/addon/{$addonId}").'">...</a>';
+}
+
+// prepare alt and title text for preview image
+$_alt = sprintf(_('img_preview_of'), $addonName);
+
+$group = isset($group) ? $group : '';
+$flags = array($group);
+
+// is addon experimental?
+global $experimental_status;
+if (isset($addonStatus) && in_array($addonStatus, $experimental_status)) {
+ $flags[] = 'experimental';
+}
+?>
+<div class="<?=join(' ', $flags)?> item">
+ <div class="item-info">
+ <?=$this->renderElement('amo2009/reviews', array('addon' => $addon))?>
+ <span class="downloads"><strong><?=$html->number_format($addonWeeklyDownloads, 0)?></strong> <?=___('addon_downloads_weekly')?></span>
+ <p class="updated">
+ <?php
+ $_update_string = ___('addon_detail_last_updated');
+ $_version_date = (isset($addonDateChanged) ? $addonDateChanged : $addonVersionCreated);
+ echo sprintf($_update_string, strftime(_('date'), strtotime($_version_date)));
+ ?>
+ </p>
+ <?=$this->renderElement('amo2009/install', array(
+ 'flags' => $flags,
+ 'addon' => $addon
+ ))?>
+ </div>
+ <h3>
+ <a title="<?=___('addons_title_tooltip') ?>" href="<?=$html->url("/addon/{$addonId}")?>"><?=$addonName?></a>
+ <span title="<?=___('addons_author_tooltip') ?>"><?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addonAuthors, 0);?></span>
+ <?php if (!empty($addonCategories)): ?>
+ <span><strong><a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonCategories[0]['Category']['id'])?>" class="view"><?=$addonCategories[0]['Translation']['name']['string']?></a></strong></span>
+ <?php endif; ?>
+ <a title="<?=___('addons_title_tooltip') ?>" href="<?=$html->url("/addon/{$addonId}")?>"><img src="<?=$addonIconPath?>" width="32" height="32" alt="<?=$_alt?>" title="<?=$_alt?>" class="icon"/></a>
+ </h3>
+ <blockquote cite="#"><p><?=$addonSummary?></p></blockquote>
+</div>
+
+<?php if (false): ?>
+<? if (!empty($flag)) echo '<h6 class="flag">'.$flag.'</h6>'; ?>
+<?php if (isset($addonFiles)): ?>
+
+<p class="updated">
+ <?php echo sprintf(___('addon_detail_last_updated'), strftime(_('date'), strtotime($addonVersionCreated))); ?>
+</p>
+
+<?=$this->renderElement('install',array(
+ 'addonType' => $addonType
+))?>
+<?php else: ?>
+<p class="learn-more"><?=$html->link(_('feature_learnmore'), "/addon/{$addonId}",
+ array('class'=>'view', 'title'=>sprintf(_('feature_learnmore_about_addon'), $addonName)))?></p>
+<?php endif; ?>
+
+<?php if(!empty($addonCategories)): ?>
+<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonCategories[0]['Category']['id'])?>" class="view"><?=$addonCategories[0]['Translation']['name']['string']?></a></p>
+<?php endif; ?>
+
+<?php endif ?> \ No newline at end of file
diff --git a/site/app/views/elements/amo2009/search.thtml b/site/app/views/elements/amo2009/search.thtml
index 1596895..bb952a7 100644
--- a/site/app/views/elements/amo2009/search.thtml
+++ b/site/app/views/elements/amo2009/search.thtml
@@ -187,18 +187,18 @@ if (!isset($category)) $category = array(0, 0);
<select name="cat" id="cat">
<option class="cat-all" value="all"<?=(!$collectionSearch && $category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
- <?php foreach ($AmoTags as $tag): ?>
+ <?php foreach ($AmoCategories as $category): ?>
<?php
// skip "plugins" as it is a static page at the moment and thus
// cannot be searched here
- if ($tag['type'] == ADDON_PLUGIN) continue;
+ if ($category['type'] == ADDON_PLUGIN) continue;
- if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ if ($category[0] == $category['type'] && ($category[1]==$category['cat'] || $category['cat']==0))
$sel = ' selected="selected"';
else
$sel = '';
?>
- <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <option value="<?=$category['type'].','.$category['cat']?>"<?=$sel?>><?=$html->entities($category['name'])?></option>
<?php endforeach; ?>
<option class="cat-all" value="collections"<?=($collectionSearch ? ' selected="selected"' : '')?>><?=___('search_form_all_collections', 'all collections')?></option>
diff --git a/site/app/views/elements/categories.thtml b/site/app/views/elements/categories.thtml
index e7cbd53..7b9c338 100644
--- a/site/app/views/elements/categories.thtml
+++ b/site/app/views/elements/categories.thtml
@@ -53,10 +53,10 @@ global $hybrid_categories;
if (isset($highlight) && !empty($highlight)) {
// find current category in category list
$highlight_cat = array();
- foreach ($AmoTags as $_tag) {
- if ($_tag['type'] == $highlight[0] &&
- ($_tag['cat'] == $highlight[1] || $_tag['cat'] == 0)) {
- $highlight_cat = $_tag;
+ foreach ($AmoCategories as $_category) {
+ if ($_category['type'] == $highlight[0] &&
+ ($_category['cat'] == $highlight[1] || $_category['cat'] == 0)) {
+ $highlight_cat = $_category;
break;
}
}
@@ -74,11 +74,11 @@ global $hybrid_categories;
// when appropriate, show sub-category
if ($highlight_cat['cat'] == 0 && $highlight[1] != 0
- && isset($this_tag)) {
+ && isset($this_category)) {
echo "<br/>&lfloor;&nbsp;"; // sub-category marker
- echo $html->link($this_tag['Translation']['name']['string'],
- $_url."/cat:{$this_tag['Tag']['id']}",
+ echo $html->link($this_category['Translation']['name']['string'],
+ $_url."/cat:{$this_category['Category']['id']}",
array('title'=>_('categories_current_title')));
}
echo "</p>";
@@ -90,9 +90,9 @@ global $hybrid_categories;
<ul id='cat-list'>
<?php
- foreach ($AmoTags as $_tag) {
- $_url = "/browse/type:{$_tag['type']}".($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
- echo '<li>'.$html->link($html->entities($_tag['name']), $_url)."</li>\n";
+ foreach ($AmoCategories as $_category) {
+ $_url = "/browse/type:{$_category['type']}".($_category['cat']!=0 ? "/cat:{$_category['cat']}" : '');
+ echo '<li>'.$html->link($html->entities($_category['name']), $_url)."</li>\n";
}
?>
</ul>
diff --git a/site/app/views/elements/collections_install_item.thtml b/site/app/views/elements/collections_install_item.thtml
index f7a91b5..3a58dbb 100644
--- a/site/app/views/elements/collections_install_item.thtml
+++ b/site/app/views/elements/collections_install_item.thtml
@@ -42,7 +42,7 @@
/**
* This element uses the following local variables:
* - $addon (Addon model-style array, containing 'Addon' and
- * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * (optionally) 'Version', 'File', 'Category' sub-arrays)
* - $addonIconPath (optional)
* - $addonPreviewPath (optional)
*/
diff --git a/site/app/views/elements/collections_interactive_addon.thtml b/site/app/views/elements/collections_interactive_addon.thtml
index eb8edbb..3468e9d 100644
--- a/site/app/views/elements/collections_interactive_addon.thtml
+++ b/site/app/views/elements/collections_interactive_addon.thtml
@@ -43,7 +43,7 @@
/**
* This element uses the following local variables:
* - $addon (Addon model-style array, containing 'Addon' and
- * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * (optionally) 'Version', 'File', 'Category' sub-arrays)
* - $addonIconPath (optional)
* - $addonPreviewPath (optional)
*/
diff --git a/site/app/views/elements/developers/adminmenu.thtml b/site/app/views/elements/developers/adminmenu.thtml
index 5208464..70dc1ab 100644
--- a/site/app/views/elements/developers/adminmenu.thtml
+++ b/site/app/views/elements/developers/adminmenu.thtml
@@ -65,9 +65,11 @@
if ($this->controller->SimpleAcl->actionAllowed('Admin', 'lists', $this->controller->Session->read('User'))): ?>
<li<?=($page == 'lists' && empty($subpage)) ? ' class="selected"' : ''?>><?=$html->link('List Manager', '/admin/lists')?></li>
<?php if ($page == 'lists'): ?>
- <li class="indented<?=($subpage == 'tags') ? ' selected' : ''?>"><?=$html->link('Categories', '/admin/tags')?></li>
+ <li class="indented<?=($subpage == 'categories') ? ' selected' : ''?>"><?=$html->link('Categories', '/admin/categories')?></li>
<li class="indented<?=($subpage == 'platforms') ? ' selected' : ''?>"><?=$html->link('Platforms', '/admin/platforms')?></li>
<li class="indented<?=($subpage == 'responses') ? ' selected' : ''?>"><?=$html->link('Responses', '/admin/responses')?></li>
+ <li class="indented<?=($subpage == 'tags') ? ' selected' : ''?>"><?=$html->link('Tags', '/admin/tags')?></li>
+
<?php endif; ?>
<?php endif;
if ($this->controller->SimpleAcl->actionAllowed('Localizers', '%', $this->controller->Session->read('User'))): ?>
diff --git a/site/app/views/elements/developers/editbox.thtml b/site/app/views/elements/developers/editbox.thtml
index 530bab1..32434a7 100644
--- a/site/app/views/elements/developers/editbox.thtml
+++ b/site/app/views/elements/developers/editbox.thtml
@@ -45,6 +45,8 @@
<li class="container"><ul>
<li class="edit-authors<?=($subaction == 'authors' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_authors'), "/developers/addon/edit/{$addon_id}/authors")?></li>
<li class="edit-categories<?=($subaction == 'categories' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_categories'), "/developers/addon/edit/{$addon_id}/categories")?></li>
+ <li class="edit-tags<?=($subaction == 'tags' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_tags'), "/developers/addon/edit/{$addon_id}/tags")?></li>
+
<li class="edit-descriptions<?=($subaction == 'descriptions' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_descriptions'), "/developers/addon/edit/{$addon_id}/descriptions")?></li>
<li class="edit-properties<?=($subaction == 'properties' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_properties'), "/developers/addon/edit/{$addon_id}/properties")?></li>
</ul></li>
diff --git a/site/app/views/elements/developers/localizermenu.thtml b/site/app/views/elements/developers/localizermenu.thtml
index 3a93664..d3396bc 100644
--- a/site/app/views/elements/developers/localizermenu.thtml
+++ b/site/app/views/elements/developers/localizermenu.thtml
@@ -42,7 +42,7 @@
<ul id="cat-list">
<li<?=($page == 'summary') ? ' class="selected"' : ''?>><?=$html->link('Localizer Summary', '/localizers/summary')?></li>
<li<?=($page == 'applications') ? ' class="selected"' : ''?>><?=$html->link('Applications', '/localizers/applications')?></li>
- <li<?=($page == 'tags') ? ' class="selected"' : ''?>><?=$html->link('Categories', '/localizers/tags')?></li>
+ <li<?=($page == 'categories') ? ' class="selected"' : ''?>><?=$html->link('Categories', '/localizers/categories')?></li>
<li<?=($page == 'collection_features') ? ' class="selected"' : ''?>><?=$html->link('Collection Features', '/localizers/collection_features')?></li>
<?php if ($this->controller->SimpleAcl->actionAllowed('Admin', 'lists', $this->controller->Session->read('User'))): ?>
<li<?=($page == 'platforms') ? ' class="selected"' : ''?>><?=$html->link('Platforms', '/localizers/platforms')?></li>
diff --git a/site/app/views/elements/feature.thtml b/site/app/views/elements/feature.thtml
index 2f43bcb..35c76b2 100644
--- a/site/app/views/elements/feature.thtml
+++ b/site/app/views/elements/feature.thtml
@@ -55,7 +55,7 @@
* - $addonAuthors
* - $addonRating
* - $addonReviews
- * - $addonTags
+ * - $addonCategories
* - $addonWeeklyDownloads
* - $allPlatforms - There should only be one platform in the list when this is used on the eula view.
* - $compatible_apps
@@ -123,7 +123,7 @@ else
array('class'=>'view', 'title'=>sprintf(_('feature_learnmore_about_addon'), $addonName)))?></p>
<?php endif; ?>
-<?php if(!empty($addonTags)): ?>
-<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonTags[0]['Tag']['id'])?>" class="view"><?=$addonTags[0]['Translation']['name']['string']?></a></p>
+<?php if(!empty($addonCategories)): ?>
+<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonCategories[0]['Category']['id'])?>" class="view"><?=$addonCategories[0]['Translation']['name']['string']?></a></p>
<?php endif; ?>
diff --git a/site/app/views/elements/search.thtml b/site/app/views/elements/search.thtml
index 755af51..b35eb2e 100644
--- a/site/app/views/elements/search.thtml
+++ b/site/app/views/elements/search.thtml
@@ -187,17 +187,17 @@ if (!isset($category)) $category = array(0, 0);
<option value="all"<?=($category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
<?php
// AmoVersions is from controller->beforeRender()
- foreach ($AmoTags as $tag):
+ foreach ($AmoCategories as $category):
// skip "plugins" as it is a static page at the moment and thus
// cannot be searched here
- if ($tag['type'] == ADDON_PLUGIN) continue;
+ if ($category['type'] == ADDON_PLUGIN) continue;
- if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ if ($category[0] == $category['type'] && ($category[1]==$category['cat'] || $category['cat']==0))
$sel = ' selected="selected"';
else
$sel = '';
?>
- <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <option value="<?=$category['type'].','.$category['cat']?>"<?=$sel?>><?=$html->entities($category['name'])?></option>
<?php endforeach; ?>
</select><?=$html->submit(" ", array('id'=>'my-submit', 'title' => ___('search_form_submit_tooltip'))); ?>
</fieldset>
diff --git a/site/app/views/elements/search_mini.thtml b/site/app/views/elements/search_mini.thtml
index be88204..41a78fe 100644
--- a/site/app/views/elements/search_mini.thtml
+++ b/site/app/views/elements/search_mini.thtml
@@ -54,17 +54,17 @@ if (!isset($query) || !is_string($query))
<option value="all"<?=($category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
<?php
// AmoVersions is from controller->beforeRender()
- foreach ($AmoTags as $tag):
+ foreach ($AmoCategories as $category):
// skip "plugins" as it is a static page at the moment and thus
// cannot be searched here
- if ($tag['type'] == ADDON_PLUGIN) continue;
+ if ($category['type'] == ADDON_PLUGIN) continue;
- if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ if ($category[0] == $category['type'] && ($category[1]==$category['cat'] || $category['cat']==0))
$sel = ' selected="selected"';
else
$sel = '';
?>
- <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <option value="<?=$category['type'].','.$category['cat']?>"<?=$sel?>><?=$html->entities($category['name'])?></option>
<?php endforeach; ?>
</select>
<button type="submit" id="search-mini-submit"><?= _('search'); ?></button>
diff --git a/site/app/views/elements/sidebar.thtml b/site/app/views/elements/sidebar.thtml
index 593e9a0..e331f88 100644
--- a/site/app/views/elements/sidebar.thtml
+++ b/site/app/views/elements/sidebar.thtml
@@ -40,7 +40,7 @@
/**
* This element uses the following local variables:
- * - $highlight tag array of category to be highlighted
+ * - $highlight category array of category to be highlighted
* - $pitch - (bool, default: false) add MDC tutorial stuff
*/
diff --git a/site/app/views/facebook/browse.thtml b/site/app/views/facebook/browse.thtml
index 801aee6..5e9393d 100644
--- a/site/app/views/facebook/browse.thtml
+++ b/site/app/views/facebook/browse.thtml
@@ -57,11 +57,11 @@
Category:
<select name="cat">
<?php
- foreach ($tags as $tagVal => $tagOption) {
- echo '<option value="'.$tagVal.'"';
- if ($tagVal == $current['cat'])
+ foreach ($categories as $categoryVal => $categoryOption) {
+ echo '<option value="'.$categoryVal.'"';
+ if ($categoryVal == $current['cat'])
echo ' selected';
- echo '>'.$tagOption.'</option>';
+ echo '>'.$categoryOption.'</option>';
}
?>
</select>&nbsp;&nbsp;
diff --git a/site/app/views/helpers/addons_html.php b/site/app/views/helpers/addons_html.php
index 1ea01f7..8ca0ba3 100644
--- a/site/app/views/helpers/addons_html.php
+++ b/site/app/views/helpers/addons_html.php
@@ -554,7 +554,7 @@ class AddonsHtmlHelper extends HtmlHelper
function isFeatured($addon) {
$featured = false;
- foreach($addon['AddonTag'] as $tag) {
+ foreach($addon['AddonCategory'] as $tag) {
if($tag['feature'] == 1) {
$featured = true;
break;
diff --git a/site/app/views/localizers/tags.thtml b/site/app/views/localizers/tags.thtml
index 72a82fb..4325122 100644
--- a/site/app/views/localizers/tags.thtml
+++ b/site/app/views/localizers/tags.thtml
@@ -39,15 +39,15 @@
<?=$this->renderElement('developers/localizermenu');?>
<div id="content-main">
- <h3>Tag Localization for <?=USERLANG?></h3>
+ <h3>category Localization for <?=USERLANG?></h3>
<?php
if (!$writeAccess) {
echo '<div class="error">You do not have write access to this locale. You can look, but won\'t be able to make any changes.</div>';
}
- echo $html->formTag('/localizers/tags');
- if (!empty($tags)) {
- foreach ($tags['en-US'] as $k => $tag) {
- $id = $tags['en-US'][$k]['Tag']['id'];
+ echo $html->formTag('/localizers/categories');
+ if (!empty($categories)) {
+ foreach ($categories['en-US'] as $k => $category) {
+ $id = $categories['en-US'][$k]['Category']['id'];
echo '<table class="translatedSection">';
echo '<tr>';
echo '<th width="5%">ID '.$id.'</th>';
@@ -56,13 +56,13 @@
echo '</tr>';
echo '<tr>';
echo '<td class="field">Name</td>';
- echo '<td class="enus">'.$tags['en-US'][$k]['Translation']['name']['string'].'</td>';
- echo '<td class="localized">'.$html->input("Tag/{$id}][name", array('value' => ($tags[USERLANG][$k]['Translation']['name']['locale'] != 'en-US' ? $tags[USERLANG][$k]['Translation']['name']['string'] : ''), 'size' => 40)).'</td>';
+ echo '<td class="enus">'.$categories['en-US'][$k]['Translation']['name']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Category/{$id}][name", array('value' => ($categories[USERLANG][$k]['Translation']['name']['locale'] != 'en-US' ? $categories[USERLANG][$k]['Translation']['name']['string'] : ''), 'size' => 40)).'</td>';
echo '</tr>';
echo '<tr>';
echo '<td class="field">Description</td>';
- echo '<td class="enus">'.$tags['en-US'][$k]['Translation']['description']['string'].'</td>';
- echo '<td class="localized">'.$html->textarea("Tag/{$id}][description", array('value' => ($tags[USERLANG][$k]['Translation']['description']['locale'] != 'en-US' ? $tags[USERLANG][$k]['Translation']['description']['string'] : ''), 'cols' => 34, 'rows' => 3)).'</td>';
+ echo '<td class="enus">'.$categories['en-US'][$k]['Translation']['description']['string'].'</td>';
+ echo '<td class="localized">'.$html->textarea("Category/{$id}][description", array('value' => ($categories[USERLANG][$k]['Translation']['description']['locale'] != 'en-US' ? $categories[USERLANG][$k]['Translation']['description']['string'] : ''), 'cols' => 34, 'rows' => 3)).'</td>';
echo '</tr>';
echo '</table>';
}
diff --git a/site/app/views/pages/appversions.thtml b/site/app/views/pages/appversions.thtml
index d719204..400fc70 100644
--- a/site/app/views/pages/appversions.thtml
+++ b/site/app/views/pages/appversions.thtml
@@ -44,7 +44,7 @@ loadComponent('Versioncompare');
$applicationModel =& new Application();
$versionCompare =& new VersioncompareComponent();
-$applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Tag')));
+$applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Category')));
$applications = $applicationModel->findAll('Application.supported=1', null, null, null, null, 2);
foreach ($applications as $application) {
diff --git a/site/app/views/search/index.thtml b/site/app/views/search/index.thtml
index d5414fe..d428aee 100644
--- a/site/app/views/search/index.thtml
+++ b/site/app/views/search/index.thtml
@@ -37,35 +37,179 @@
*
* ***** END LICENSE BLOCK ***** */
-$this->viewVars['bodyclass'] = 'inverse';
+// $this->viewVars['bodyclass'] = 'inverse';
$this->layout = 'amo2009';
+global $app_shortnames, $app_prettynames;
+
+// This is the string that I pass to 'hrefs' to Filter the results. Has to be a better way:
+// $html->url("/search?q=".$search_terms."&appid=".$appid."&cat=".$category[0].",".$category[1]."&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$hver."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp)
?>
+
+
+
<div class="section">
<div class="stand-alone-options">
<?=$this->renderElement('amo2009/categories')?>
- <?=$this->renderElement('amo2009/search', array('query'=>$search_terms,
+ <?=$this->renderElement('amo2009/search', array('query'=>$search_terms,
'category'=>$category, 'appid'=>$appid, 'atype'=>$atype, 'lup'=>"$lup",
'pid'=>$pid, 'sort'=>$sort, 'hver'=>$hver, 'lver'=>$lver, 'vfuz'=>$vfuz, 'pp'=>$pp))?>
</div>
<?php // TODO Remove style when new search design is implemented; bug 482857 ?>
- <div class="primary" style="width:100%;">
- <?=$this->renderElement('amo2009/breadcrumbs')?>
-
- <div class="featured listing">
+ <div class="primary results-head">
+ <h2><span>Search Results</span></h2>
+<?php if (!empty($search_results)): ?>
+ <h3 class="result-count">Showing <?=$offset + 1?> - <?=$offset + count($search_results)?> of <?=$total_count?> results <?= (!empty($search_terms)) ? "for <strong>".$search_terms."</strong>" : "" ?></h3>
+<?php endif; ?>
+ </div>
+<?php if (empty($search_results)): ?>
+ <div class="primary" role="main" style="width: 100%">
+<?php else: ?>
+ <div class="primary" role="main">
+<?php endif; ?>
+ <div class="featured listing results">
<div class="featured-inner">
<div class="listing-header">
- <?php if (empty($search_results)): ?>
+ <?php if (empty($search_results)): ?>
<p class="addon-search-message"><?=_('search_nothing_found')?></p>
+ <?php else : ?>
+ <ul>
+ <?php
+ foreach (array_keys($app_shortnames) as $_app) {
+ if ($app_shortnames[$_app] == APP_FENNEC) continue;
+ $class = ($app_shortnames[$_app] == $appid) ? ' class="selected"' : '';
+ echo '<li'.$class.'><a href="'.$html->url("/search?q=".$search_terms."&appid=".$app_shortnames[$_app]."&cat=".$category[0].",".$category[1]."&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$hver."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp).'">'.$app_prettynames[$_app].'</a></li>';
+ }
+ ?>
+ </ul>
+ <form class="item-sort" method="get" action="">
+ <label><?=___('advanced_search_form_sortby'); ?></label>
+ <?php
+ $sort_orders = array(
+ '' => ___('advanced_search_form_keyword_match'),
+ 'newest' => ___('advanced_search_form_newest'),
+ 'name' => ___('advanced_search_form_name'),
+ 'averagerating' => ___('advanced_search_form_rating'),
+ 'weeklydownloads' => ___('advanced_search_form_popularity')
+ );
+ $html->simpleSelectTag('sort', $sort_orders, $sort, array(), array(), false);
+ ?>
+ <button><?=___('collections_index_button_go')?></button>
+ </form>
+ <script type="text/javascript">collections.init();</script>
<?php endif; ?>
</div> <!-- listing-header -->
- <?php
- foreach ($search_results as $var => $val) {
- echo $this->renderElement('amo2009/homepage_addon', array('addon' => $val));
- }
- ?>
+ <?php foreach ($search_results as $var => $val): ?>
+ <?=$this->renderElement('amo2009/results_addon', array('addon' => $val));?>
+ <?php endforeach; ?>
+ <?php if (count($search_results) > 0): ?>
+ <div class="listing-footer">
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div>
+ <?php endif; ?>
</div> <!-- featured-inner -->
<?=$this->renderElement('amo2009/listing_footer')?>
</div> <!-- featured listing -->
</div> <!-- primary -->
+<?php if (!empty($search_results)): ?>
+ <div class="secondary" role="complimentary">
+ <div class="highlight">
+ <h2>Refine Results</h2>
+ <div id="refine-compatibility">
+ <h5>Compatible with</h5>
+ <ul class="refinements">
+ <?php
+ $selected = "";
+ if ($hver == "any") {
+ $selected = " class='selected'";
+ }
+ echo '<li'.$selected.'><a href="'.$html->url("/search?q=".$search_terms."&appid=".$appid."&cat=".$category[0].",".$category[1]."&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=any&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp).'">All versions</a></li>';
+ ?>
+ <?php
+ $min_display_version_by_app = array(
+ APP_FIREFOX => "1.0",
+ APP_THUNDERBIRD => "1.0",
+ APP_SEAMONKEY => "1.0",
+ APP_SUNBIRD => "0.2"
+ );
+
+ $new_versions = array();
+ foreach ($app_shortnames as $n => $k) {
+ if (!empty($AmoVersions[$k])) foreach ($AmoVersions[$k] as $version) {
+ $versions_parts = explode(".", $version);
+ $second_part = (isset($versions_parts[1])) ? ".".intval($versions_parts[1]) : "";
+ if (!isset($min_display_version_by_app[$k])
+ || $min_display_version_by_app[$k] <= $versions_parts[0].$second_part ) {
+
+ if ($k != APP_FIREFOX || !in_array($versions_parts[0].$second_part, array('1.4','3.1'))) {
+ $new_versions[$k][] = $versions_parts[0].$second_part;
+ }
+ }
+ }
+ if (!empty($new_versions[$k]))
+ $new_versions[$k] = array_unique($new_versions[$k]);
+ }
+ $versions = $new_versions;
+ foreach (array_reverse($versions[$appid]) as $app_version){
+ $selected = "";
+ if ($app_version == $hver) {
+ $selected = " class='selected'";
+ }
+ echo '<li'.$selected.'><a href="'.$html->url("/search?q=".$search_terms."&appid=".$appid."&cat=".$category[0].",".$category[1]."&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$app_version."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp).'">'.$app_version.'</a></li>';
+ }
+ ?>
+ </ul>
+ </div>
+ <div id="refine-category">
+ <h5>Categories</h5>
+ <ul class="refinements">
+ <?php
+ if ($category == array(0,0)) {
+ $selected = ' class="selected"';
+ } else {
+ $selected = "";
+ }
+ echo '<li'.$selected.'><a href="'.$html->url("/search?q=".$search_terms."&appid=".$appid."&cat=all&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$hver."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp).'">All</a></li>';
+ $results_categories = array();
+ foreach ($search_results as $addon) {
+ if (!empty($addon['Category'])) {
+ array_push($results_categories, $addon['Category'][0]);
+ }
+ }
+ $results_categories = array_unique($results_categories);
+ foreach ($results_categories as $_categories) {
+ if ($category == array($_categories['Category']['addontype_id'], $_categories['Category']['id'])) {
+ $selected = ' class="selected"';
+ } else {
+ $selected = "";
+ }
+ echo '<li'.$selected.'><a href="'.$html->url("/search?q=".$search_terms."&appid=".$appid."&cat=".$_categories['Category']['addontype_id'].",".$_categories['Category']['id']."&tag=".$tag."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$app_version."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp).'">'.$_categories['Translation']['name']['string'].'</a></li>';
+ }
+ ?>
+ </ul>
+ </div>
+ <div id="refine-tags">
+ <h5>Tags</h5>
+ <ul class="refinements addon-tags">
+ <!-- <li class="usertag selected"><a class="tagitem" href="#">Tag</a></li>
+ <li class="usertag"><a class="tagitem" href="#">Tag 2</a></li> -->
+ <?php
+ $tag_ids = array();
+
+ foreach ($search_results as $addon) {
+ foreach ($addon['Tag'] as $t) {
+ array_push($tag_ids, $t);
+ }
+ }
+ foreach (array_unique($tag_ids) as $_tag) {
+ $search_query = $html->url("/search?q=".$search_terms."&appid=".$appid."&cat=".$category[0].",".$category[1]."&tag=".$_tag['tag_text']."&atype=".$atype."&pid=".$pid."&lup=".$lup."&sort=".$sort."&hver=".$hver."&lver=".$lver."&vfuz=".$vfuz."&pp=".$pp);
+ echo "<li class='usertag'><a class='tagitem' href='".$search_query."'>".$_tag['tag_text']."</a></li>";
+ }
+ ?>
+ </ul>
+
+ </div>
+ </div>
+ </div>
+<?php endif; ?>
</div><!-- /#section -->
diff --git a/site/app/views/sharing_api/addon.thtml b/site/app/views/sharing_api/addon.thtml
index 3a94172..2d92c47 100644
--- a/site/app/views/sharing_api/addon.thtml
+++ b/site/app/views/sharing_api/addon.thtml
@@ -50,8 +50,8 @@ if (empty($addonIconPath)) {
<?php if (isset($base_url)): ?><collection href=".." /><?php endif ?>
</meta>
<categories>
- <?php foreach ($addon['tags'] as $tag): ?>
- <category id="<?php echo $tag['id'] ?>"><?php echo $tag['name'] ?></category>
+ <?php foreach ($addon['categories'] as $category): ?>
+ <category id="<?php echo $category['id'] ?>"><?php echo $category['name'] ?></category>
<?php endforeach ?>
</categories>
<name><?php echo $addon['name']; ?></name>
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/tags/ajax/tag_added.thtml
index c95a1cf..338c81e 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/tags/ajax/tag_added.thtml
@@ -15,11 +15,13 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
+ * The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -33,34 +35,11 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
- * ***** END LICENSE BLOCK ***** */
+ * ***** END LICENSE BLOCK ***** */
+
+//$this->layout = 'amo2009';
?>
-<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
+<?=$this->renderElement('addon_tags',$relatedTags);
+if (!empty($message)) { ?><div id='tagMessage' class="tagnotice <?=$status?>"><?=$message?></div><? }
- <div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
- }
- echo $html->formTag('/admin/tags/create');
- ?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
-</div>
+ ?> \ No newline at end of file
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/tags/ajax/tag_lookup.thtml
index c95a1cf..80aa288 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/tags/ajax/tag_lookup.thtml
@@ -15,11 +15,12 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2007
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -34,33 +35,13 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-?>
-<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
- <div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
- }
- echo $html->formTag('/admin/tags/create');
- ?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
-</div>
+
+
+header('Content-type: text/plain');
+
+if (!empty($tags)) {
+ foreach ($tags as &$tag) {
+ echo $tag['Tag']['tag_text'] . "\n";
+ }
+}
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/tags/tag_added.thtml
index c95a1cf..ee82f53 100644
--- a/site/app/views/admin/tags_create.thtml
+++ b/site/app/views/tags/tag_added.thtml
@@ -15,11 +15,13 @@
* The Original Code is addons.mozilla.org site.
*
* The Initial Developer of the Original Code is
- * Justin Scott <fligtar@gmail.com>.
+ * The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -33,34 +35,11 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
- * ***** END LICENSE BLOCK ***** */
+ * ***** END LICENSE BLOCK ***** */
+
+//$this->layout = 'amo2009';
?>
-<div id="content">
- <?=$this->renderElement('developers/adminmenu');?>
+<?=$this->renderElement('addon_tags',array('userTags'=>$userTags, 'developerTags'=>$developerTags, 'origin'=>'users'));
+if (!empty($message)) { ?><div id='tagMessage' class="tagnotice <?=$status?>"><?=$message?></div><? }
- <div id="content-main">
- <h3>Create Category</h3>
- <?php
- if (!empty($errors['main'])) {
- echo '<div class="error">'.$errors['main'].'</div>';
- }
- echo $html->formTag('/admin/tags/create');
- ?>
- <div id="developersForm">
- <div>
- <label for="TagApplicationId">Application</label>
- <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
- </div>
- <div>
- <label for="TagAddontypeId">Add-on Type</label>
- <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
- </div>
- <?=$this->renderElement('developers/localebox')?>
- <div class="buttonBox">
- <?=$html->submit('Create Category')?>
- </div>
- </div>
- </form>
- <?=$html->link('Back to Category Manager', '/admin/tags')?>
- </div>
-</div>
+ ?> \ No newline at end of file
diff --git a/site/app/views/tags/top.thtml b/site/app/views/tags/top.thtml
new file mode 100644
index 0000000..63541ab
--- /dev/null
+++ b/site/app/views/tags/top.thtml
@@ -0,0 +1,10 @@
+<h2>Top <?=$numTags?> Tags</h2>
+<?
+ //print_r($topTags);
+ echo "<ul>";
+ foreach( $topTags as $tagInfo ) {
+ echo "<li><a href=\"/addons/fortag/". $tagInfo['Tag']['id'] . "\">".$tagInfo['Tag']['tag_text']."</a></li>";
+
+ }
+ echo "</ul>";
+?> \ No newline at end of file
diff --git a/site/app/views/users/info.thtml b/site/app/views/users/info.thtml
index ab70159..85c85ad 100644
--- a/site/app/views/users/info.thtml
+++ b/site/app/views/users/info.thtml
@@ -98,8 +98,8 @@
<?
global $app_shortnames;
foreach($addons as &$addon):
- if (array_key_exists('Tag', $addon) && !empty($addon['Tag'])) {
- $_application = array_search($addon['Tag'][0]['application_id'], $app_shortnames);
+ if (array_key_exists('Category', $addon) && !empty($addon['Category'])) {
+ $_application = array_search($addon['Category'][0]['application_id'], $app_shortnames);
} else {
$_application = 'firefox';
}
diff --git a/site/app/webroot/css/amo2009/main-mozilla.css b/site/app/webroot/css/amo2009/main-mozilla.css
index 4bc4ed4..2ad7063 100644
--- a/site/app/webroot/css/amo2009/main-mozilla.css
+++ b/site/app/webroot/css/amo2009/main-mozilla.css
@@ -2134,3 +2134,80 @@ html[xmlns] .clearfix {
#license a {
font-size: 0.9em;
}
+
+/**
+ * Tag classes, from 1 to 10, 10 being the largest
+ */
+
+.tagLevel1 {font-size: 1em;}
+.tagLevel2 {font-size: 1.2em;}
+.tagLevel3 {font-size: 1.4em;}
+.tagLevel4 {font-size: 1.6em;}
+.tagLevel5 {font-size: 1.8em;}
+.tagLevel6 {font-size: 2em;}
+.tagLevel7 {font-size: 2.2em;}
+.tagLevel8 {font-size: 2.4em;}
+.tagLevel9 {font-size: 2.6em;}
+.tagLevel10 {font-size: 3em;}
+
+/** tag styles **/
+.addon-tags .usertag .tagitem {
+ padding-left: 20px;
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ background-position: 0px -600px;
+}
+
+.addon-tags .developertag .tagitem {
+ padding-left: 20px;
+ xbackground-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ xbackground-position: 0px -700px;
+ background-image: url(../../img/amo2009/icons/tag_green.png);
+}
+
+
+.addon-tags li .removetag {
+ display:none;
+}
+.addon-tags li.hover .removetag,
+#tags .nojs li .removetag {
+ display:inline;
+}
+
+#tags #tagMessage {
+ background-color: #FFFFFF;
+ color:#666666;
+ display:block;
+ font-size:0.769em;
+ font-weight:normal;
+ line-height:1em;
+ text-shadow:1px 1px 1px #FFFFFF;
+ text-transform:uppercase;
+ padding: 4px;
+}
+
+.results-head {width: 100%;}
+.results-head h2 { margin-bottom: 0;}
+.results-head h3 {margin-top: 0; font-family: "helvetica neue", arial, helvetica, sans-serif; font-weight: normal; color: #444;}
+
+.results .item .item-info .downloads {display: block; margin-left: 0px;}
+.results .item .install {float: none; margin-left: 0px;}
+
+.secondary ul.refinements li a { padding: 0.21em 1.2em; display: block; color: #444; font-weight: normal;}
+.secondary ul.refinements li.selected a {
+ background-color: #b9dbe7;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ font-weight: bold;
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position:4px -152px;
+}
+.secondary ul.refinements li a.tagitem {
+ padding: 0.21em 2em;
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ background-position: 3px -596px;
+}
diff --git a/site/app/webroot/css/autocomplete.css b/site/app/webroot/css/autocomplete.css
new file mode 100644
index 0000000..6f01490
--- /dev/null
+++ b/site/app/webroot/css/autocomplete.css
@@ -0,0 +1,49 @@
+.ac_input {
+ /* width: 400px; */
+}
+.ac_results {
+ padding: 0px;
+ border: 1px solid WindowFrame;
+ background-color: Window;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 400px;
+}
+
+.ac_results ul {
+ width: 100%;
+ list-style-position: outside;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.ac_results iframe {
+ display:none;/*sorry for IE5*/
+ display/**/:block;/*sorry for IE5*/
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:-1;
+ filter:mask();
+ width:3000px;
+ height:3000px;
+}
+
+.ac_results li {
+ margin: 0px;
+ padding: 2px 5px;
+ cursor: pointer;
+ display: block;
+ width: 100%;
+ font: menu;
+ font-size: 12px;
+ overflow: hidden;
+}
+.ac_loading {
+ background : url('../img/ajax_loading.gif') right center no-repeat;
+}
+.ac_over {
+ background-color: Highlight;
+ color: HighlightText;
+} \ No newline at end of file
diff --git a/site/app/webroot/css/developers.css b/site/app/webroot/css/developers.css
index 6bd440a..4dca4cf 100644
--- a/site/app/webroot/css/developers.css
+++ b/site/app/webroot/css/developers.css
@@ -1080,11 +1080,11 @@ div.addonName {
}
.buttonBox .cancel:hover {
}
-#tagDescription {
+#categoryDescription {
vertical-align: top;
padding-left: 20px;
}
-.html-rtl #tagDescription {
+.html-rtl #categoryDescription {
padding-left: auto;
padding-right: 20px;
}
@@ -1177,3 +1177,72 @@ div.addonName {
margin-right: 14em;
}
+/** tags styles **/
+
+.addon-tags .usertag .tagitem {
+ padding-left: 20px;
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ background-position: 0px -600px;
+}
+
+.addon-tags .developertag .tagitem {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ background-image: url(../../img/amo2009/icons/tag_green.png);
+}
+
+
+.addon-tags {
+ list-style-image:none;
+ list-style-position:outside;
+ list-style-type:none;
+}
+
+.addon-tags li .removetag {
+ display:none;
+}
+.addon-tags li.hover .removetag,
+#tags .nojs li .removetag {
+ display:inline;
+}
+
+#addtagbutton {
+ -moz-border-radius-bottomleft:13px;
+ -moz-border-radius-bottomright:13px;
+ -moz-border-radius-topleft:13px;
+ -moz-border-radius-topright:13px;
+ background-color:#73B9FF;
+ background-image:url(../../img/amo2009/bg/button-blue.jpg);
+ background-position:center center;
+ background-repeat:repeat-x;
+ border:1px solid #258BFF;
+ color:#FFFFFF;
+ cursor:pointer;
+ font-family:helvetica,arial,sans-serif;
+ font-size:1em;
+ margin:0.3em 0;
+ overflow:visible;
+ padding:0 0.6em 0 0.5em;
+ text-decoration:none;
+ text-shadow:-1px -1px 1px #196CF2;
+ vertical-align:middle;
+ white-space:nowrap;
+}
+
+#tags #tagMessage {
+ background-color: #FFFFFF;
+ color:#666666;
+ display:block;
+ font-size:0.769em;
+ font-weight:normal;
+ line-height:1em;
+ text-shadow:1px 1px 1px #FFFFFF;
+ text-transform:uppercase;
+ padding: 4px;
+}
+
+
+
+
+ */ \ No newline at end of file
diff --git a/site/app/webroot/js/editors.js b/site/app/webroot/js/editors.js
index 787711a..d8eab46 100644
--- a/site/app/webroot/js/editors.js
+++ b/site/app/webroot/js/editors.js
@@ -286,7 +286,7 @@ function addNewFeatureRowBeforeElement(sibling, tagid, addonid, addonname) {
addonform.setAttribute('method', 'post');
var addonforminputlocale = document.createElement('input');
- addonforminputlocale.setAttribute('name', 'data[AddonTag][feature_locales]');
+ addonforminputlocale.setAttribute('name', 'data[AddonCategory][feature_locales]');
addonforminputlocale.setAttribute('id', 'edit-addon-locales-' + tagid + '-' + addonid);
addonforminputlocale.setAttribute('size', '40');
addonforminputlocale.setAttribute('type', 'text');
diff --git a/site/app/webroot/js/simile/ajax/simile-ajax-api.js b/site/app/webroot/js/simile/ajax/simile-ajax-api.js
index 188e17e..d798451 100755
--- a/site/app/webroot/js/simile/ajax/simile-ajax-api.js
+++ b/site/app/webroot/js/simile/ajax/simile-ajax-api.js
@@ -25,7 +25,7 @@ if (typeof SimileAjax == "undefined") {
*/
var getHead = function(doc) {
- return doc.getElementsByTagName("head")[0];
+ return doc.getElementsBycategoryName("head")[0];
};
SimileAjax.findScript = function(doc, substring) {
diff --git a/site/app/webroot/js/tags.js b/site/app/webroot/js/tags.js
new file mode 100644
index 0000000..5a683f5
--- /dev/null
+++ b/site/app/webroot/js/tags.js
@@ -0,0 +1,80 @@
+
+
+function addTag() {
+ // mod_rewrite doesn't play well with quotes
+
+ var tagVal = $("#newTag").val();
+ var addonid = $("#tags ul").attr("id").split("addonid-")[1];
+
+ if($.trim(tagVal)=='' || $.trim(addonid)==''){
+ return;
+ }
+ $.get("/tags/add_ajax/"+addonid+"/" + urlencode(tagVal), function(data) {
+ $("#tags").html(data);
+ $(".addtagform form")[0].reset();
+ $("#tags .addon-tags").removeClass("nojs");
+ });
+};
+
+ // PHP-compatible urlencode() for Javascript from http://us.php.net/manual/en/function.urlencode.php#85903
+ function urlencode(s) {
+ s = encodeURIComponent(s);
+ return s.replace(/~/g,'%7E').replace(/%20/g,'+');
+ };
+
+function remTag(addonid, tagid){
+ //var addonid = '<?= $addon['Addon']['id']; ?>';
+ $.get("/tags/remove_ajax/"+ addonid +"/"+ tagid, function(data){
+ $("#tags").html(data);
+ $(".addtagform form")[0].reset();
+ $("#tags .addon-tags").removeClass("nojs");
+ });
+};
+
+$(document).ready(function(){
+ //remove nojs classname so that css will hide the x's
+ $("#tags .addon-tags").removeClass("nojs");
+ //hide add tag form if you have js
+ $(".addtagform ").addClass("hidden");
+
+ $("#addtagbutton").click(function(e){
+ addTag();
+ e.preventDefault();
+ e.stopPropagation();
+ });
+ $("#tags .removetag").live("click",function(e){
+ var tagid = $(this).attr("id").split("remtag-")[1];
+ var addonid = $(this).parents("ul").attr("id").split("addonid-")[1];
+ //var tagid = $(this).parent().find(".tagitem").text();
+ remTag(addonid,tagid);
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ $("#tags .developertag, #tags .usertag")
+ .live("mouseover",function(){
+ $(this).addClass("hover");
+ })
+ .live("mouseout",function(){
+ $(this).removeClass("hover");
+ });
+
+ $("#addatag").click(function(e){
+ $(".addtagform")
+ .removeClass("hidden")
+ .attr("style","display:block;");
+ e.preventDefault();
+ e.stopPropagation();
+ });
+
+ $("#newTag").live("keypress",function(e){
+ //alert(e.keyCode);
+ if($.trim($(this).val()) != '' && e.keyCode == 13) {
+ console.log("add tag")
+ $("#addtagbutton").click();
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ });
+})