diff options
author | wclouser@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) |
commit | ab56f9f38526d5a9a05be9ebc07a18632907fcfa (patch) | |
tree | a80e7c520e0d72d3e83bc93da3843557bf17f6e2 | |
parent | 07b2ade1f4d8827b5d6684c665ccfc473270f1ba (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
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).': '; - 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"' : '').' /> '; + 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"' : '').' /> '; 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 ' '; 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'], )).' '; - 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/>⌊ "; // 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> 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(); + } + + }); +}) |