diff --git a/admin/themes/default/collections/browse.php b/admin/themes/default/collections/browse.php index 7577abcfb8..cd0dc07b9c 100644 --- a/admin/themes/default/collections/browse.php +++ b/admin/themes/default/collections/browse.php @@ -1,8 +1,10 @@ getTable('Item')->count(array('collection' => 0)); echo head(array('title'=>$pageTitle, 'bodyclass'=>'collections browse')); echo flash(); +echo collection_search_filters(); ?> 0): ?> @@ -12,6 +14,7 @@ +

+

+ + +

diff --git a/admin/themes/default/collections/quick-filters.php b/admin/themes/default/collections/quick-filters.php new file mode 100644 index 0000000000..d608e1721d --- /dev/null +++ b/admin/themes/default/collections/quick-filters.php @@ -0,0 +1,11 @@ + diff --git a/admin/themes/default/css/style.css b/admin/themes/default/css/style.css index efeb1ebaee..3a1bbbd9ec 100644 --- a/admin/themes/default/css/style.css +++ b/admin/themes/default/css/style.css @@ -275,7 +275,7 @@ img { overflow: visible; float: left; margin-right: 14px; } - .image img { +.image img { width: 50px; height: auto; float: left; } @@ -286,6 +286,66 @@ dt { dd { margin-top: 10px; } +legend { + font-size: 21px; + font-weight: normal; + margin-bottom: 16px; + padding: 0; + } + + input, select, textarea, button, a.button { + font-family: inherit; + font-size: 100%; + } + + input.color { + font-family: monospace; + } + + input[type=text], input[type=password], input[type=email] { + height: 30px; + border: 1px solid #d8d8d8; + -webkit-border-radius: 0; + -moz-box-radius: 0; + border-radius: 0; + -webkit-box-shadow: 0 0 .375em #d6d6d6 inset; + -moz-box-shadow: 0 0 .375em #d6d6d6 inset; + box-shadow: 0 0 .375em #d6d6d6 inset; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #666666; + line-height: 20px; + margin: 0 0 10px 0; + padding: 5px 10px; + } + + input[type=text].big { + padding: .375em; + } + + input[type=text].small { + padding: 0; + } + + .field { + clear: both; + } + + .field label { + clear: left; + font-weight: bold; + float: left; + line-height: 1.5em; + margin: 0 0 10px 0; + min-width: 120px; + } + + .field select { + width: 100%; + margin-bottom: 10px; + } + .exhibit .image, .collection .image { -webkit-box-shadow: -6px -6px rgba(0, 0, 0, 0.1); @@ -576,6 +636,13 @@ button.ui-dialog-titlebar-close { z-index: 9; position: relative; } + .inputs input[type=text], .inputs input[type=password], .inputs input[type=email], .inputs textarea { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .panel { width: 100%; background-color: #fff; @@ -1896,6 +1963,26 @@ ul.details { .add.button { float: left; } +.items.browse #advanced-search-link { + float: left; + margin-bottom: 20px; +} + + #item-filters ul, #collection-filters ul { + clear: both; + list-style-type: none; + padding: 0; + margin: 0; +} + + #item-filters li, #collection-filters li { + display: inline-block; + background: url('../images/search.png') no-repeat; + padding: 0 0 0 21px; + margin: 0 30px 20px 0; + background-position-y: 2px; + } + #type-metadata-form .offset-by-two { margin-left: 28%; } @media (min-width: 768px) and (max-width: 991px) { diff --git a/admin/themes/default/index.php b/admin/themes/default/index.php index 4debe68a2a..eb39a97f03 100644 --- a/admin/themes/default/index.php +++ b/admin/themes/default/index.php @@ -51,7 +51,7 @@

@@ -69,7 +69,7 @@

diff --git a/admin/themes/default/items/batch-edit.php b/admin/themes/default/items/batch-edit.php index 7dd57a4cf0..12e6c05fb8 100644 --- a/admin/themes/default/items/batch-edit.php +++ b/admin/themes/default/items/batch-edit.php @@ -1,4 +1,6 @@ ">
+

diff --git a/admin/themes/default/javascripts/collections-browse.js b/admin/themes/default/javascripts/collections-browse.js new file mode 100644 index 0000000000..b051c7b759 --- /dev/null +++ b/admin/themes/default/javascripts/collections-browse.js @@ -0,0 +1,39 @@ +if (!Omeka) { + var Omeka = {}; +} + +Omeka.CollectionsBrowse = {}; + +(function ($) { + Omeka.CollectionsBrowse.setupDetails = function (detailsText, showDetailsText, hideDetailsText) { + $('.details').hide(); + $('.action-links').prepend(' '); + + $('tr.collection').each(function() { + var collectionDetails = $(this).find('.details'); + if ($.trim(collectionDetails.html()) != '') { + $(this).find('.details-link').css({'color': '#4E7181', 'cursor': 'pointer'}).click(function() { + collectionDetails.slideToggle('fast'); + }); + } + }); + + var toggleList = '' + showDetailsText + ''; + + $('.quick-filter-wrapper').before(toggleList); + + // Toggle collection details. + var detailsShown = false; + $('.toggle-all-details').click(function (e) { + e.preventDefault(); + if (detailsShown) { + $('.toggle-all-details').text(showDetailsText); + $('.details').slideUp('fast'); + } else { + $('.toggle-all-details').text(hideDetailsText); + $('.details').slideDown('fast'); + } + detailsShown = !detailsShown; + }); + }; +})(jQuery); diff --git a/application/controllers/AppearanceController.php b/application/controllers/AppearanceController.php index 6d1fdac64d..69fb612c28 100644 --- a/application/controllers/AppearanceController.php +++ b/application/controllers/AppearanceController.php @@ -14,6 +14,7 @@ class AppearanceController extends Omeka_Controller_AbstractActionController const DEFAULT_FULLSIZE_CONSTRAINT = 800; const DEFAULT_THUMBNAIL_CONSTRAINT = 200; const DEFAULT_SQUARE_THUMBNAIL_CONSTRAINT = 200; + const DEFAULT_RECENT_ADMIN = 5; const DEFAULT_PER_PAGE_ADMIN = 10; const DEFAULT_PER_PAGE_PUBLIC = 10; diff --git a/application/controllers/TagsController.php b/application/controllers/TagsController.php index ecec1f54de..70a8c165ed 100644 --- a/application/controllers/TagsController.php +++ b/application/controllers/TagsController.php @@ -88,6 +88,23 @@ protected function _getBrowseDefaultSort() return array('name', 'a'); } + protected function _getDeleteConfirmMessage($tag) + { + return __('This will delete the tag "%s" from all records associated to it.', $tag->name); + } + + /** + * Redirect to another page after a record is successfully deleted. + * + * The default is to redirect to this controller's browse page. + * + * @param Omeka_Record_AbstractRecord $record + */ + protected function _redirectAfterDelete($record) + { + $this->_helper->redirector('browse'); + } + public function autocompleteAction() { $tagText = $this->_getParam('term'); @@ -109,8 +126,15 @@ public function renameAjaxAction() $oldTag->name = $newName; $this->_helper->viewRenderer->setNoRender(); - if ($csrf->isValid($_POST) && $oldTag->save(false)) { - $this->getResponse()->setBody($newName); + if ($csrf->isValid($_POST)) { + if ($oldTag->save(false)) { + $this->getResponse()->setBody($newName); + } else { + $newTag = $this->_helper->db->findOrNew($newName); + $newTagId = $newTag->id; + $count = $this->_helper->db->mergeTags($oldTagId, $newTagId); + $this->getResponse()->setBody($newName); + } } else { $this->getResponse()->setHttpResponseCode(500); $this->getResponse()->setBody($error); diff --git a/application/forms/AppearanceSettings.php b/application/forms/AppearanceSettings.php index 674b92f597..2cebf2b483 100644 --- a/application/forms/AppearanceSettings.php +++ b/application/forms/AppearanceSettings.php @@ -44,6 +44,13 @@ public function init() 'required' => true, )); + $this->addElement('text', 'recent_admin', array( + 'label' => __('Recents Items/Collections (admin)'), + 'description' => __('Limit the number of recent Items and Collections displayed in the administrative inteface.'), + 'validators' => array('Digits'), + 'required' => true, + )); + $this->addElement('text', 'per_page_admin', array( 'label' => __('Results Per Page (admin)'), 'description' => __('Limit the number of results displayed per page in the administrative interface.'), @@ -101,7 +108,7 @@ public function init() $this->addDisplayGroup( array( - 'use_square_thumbnail', 'link_to_file_metadata', 'per_page_admin', 'per_page_public', + 'use_square_thumbnail', 'link_to_file_metadata', 'recent_admin', 'per_page_admin', 'per_page_public', 'show_empty_elements', 'show_element_set_headings', ), 'display-settings', array('legend' => __('Display Settings')) diff --git a/application/forms/Install.php b/application/forms/Install.php index d9297d0cd6..f573974aa8 100644 --- a/application/forms/Install.php +++ b/application/forms/Install.php @@ -15,6 +15,7 @@ class Omeka_Form_Install extends Omeka_Form const DEFAULT_FULLSIZE_CONSTRAINT = 800; const DEFAULT_THUMBNAIL_CONSTRAINT = 200; const DEFAULT_SQUARE_THUMBNAIL_CONSTRAINT = 200; + const DEFAULT_RECENT_ADMIN = 5; const DEFAULT_PER_PAGE_ADMIN = 10; const DEFAULT_PER_PAGE_PUBLIC = 10; const DEFAULT_SHOW_EMPTY_ELEMENTS = false; @@ -213,6 +214,14 @@ public function init() 'required' => true )); + $this->addElement('text', 'recent_admin', array( + 'label' => __('Recent Items/Collections (admin)'), + 'description' => __('Limit the number of recent Items and Collections displayed in the administrative inteface.'), + 'value' => self::DEFAULT_RECENT_ADMIN, + 'validators' => array('Digits'), + 'required' => true + )); + $this->addElement('text', 'per_page_admin', array( 'label' => __('Items Per Page (admin)'), 'description' => __('Limit the number of items displayed per page in the administrative interface.'), @@ -275,8 +284,8 @@ public function init() array('administrator_email', 'site_title', 'description', 'copyright', 'author', 'tag_delimiter', 'fullsize_constraint', 'thumbnail_constraint', 'square_thumbnail_constraint', - 'per_page_admin', 'per_page_public', 'show_empty_elements', - 'path_to_convert'), + 'recent_admin', 'per_page_admin', 'per_page_public', + 'show_empty_elements', 'path_to_convert'), 'site_settings', array('legend' => __('Site Settings')) ); diff --git a/application/libraries/globals.php b/application/libraries/globals.php index 2e764d890c..890e839e9c 100644 --- a/application/libraries/globals.php +++ b/application/libraries/globals.php @@ -2036,6 +2036,19 @@ function item_search_filters(array $params = null) return get_view()->itemSearchFilters($params); } +/** + * Get a list of the current search collection filters in use. + * + * @package Omeka\Function\Search + * @uses Omeka_View_Helper_SearchFilters::searchFilters() + * @params array $params Params to override the ones read from the request. + * @return string + */ +function collection_search_filters(array $params = null) +{ + return get_view()->collectionSearchFilters($params); +} + /** * Get metadata for a record. * diff --git a/application/models/Installer/Default.php b/application/models/Installer/Default.php index 9e679700d9..da20f99aa3 100644 --- a/application/models/Installer/Default.php +++ b/application/models/Installer/Default.php @@ -106,6 +106,7 @@ private function _addOptions() 'thumbnail_constraint' => $this->_getValue('thumbnail_constraint'), 'square_thumbnail_constraint' => $this->_getValue('square_thumbnail_constraint'), 'fullsize_constraint' => $this->_getValue('fullsize_constraint'), + 'recent_admin' => $this->_getValue('recent_admin'), 'per_page_admin' => $this->_getValue('per_page_admin'), 'per_page_public' => $this->_getValue('per_page_public'), 'show_empty_elements' => $this->_getValue('show_empty_elements'), diff --git a/application/models/Installer/Task/Options.php b/application/models/Installer/Task/Options.php index a2f77ca0ef..0434441b9f 100644 --- a/application/models/Installer/Task/Options.php +++ b/application/models/Installer/Task/Options.php @@ -22,6 +22,7 @@ class Installer_Task_Options implements Installer_TaskInterface 'thumbnail_constraint', 'square_thumbnail_constraint', 'fullsize_constraint', + 'recent_admin', 'per_page_admin', 'per_page_public', 'show_empty_elements', diff --git a/application/models/Installer/Test.php b/application/models/Installer/Test.php index f327231610..2c67f50490 100644 --- a/application/models/Installer/Test.php +++ b/application/models/Installer/Test.php @@ -24,6 +24,7 @@ class Installer_Test extends Installer_Default 'thumbnail_constraint' => Omeka_Form_Install::DEFAULT_THUMBNAIL_CONSTRAINT, 'square_thumbnail_constraint' => Omeka_Form_Install::DEFAULT_SQUARE_THUMBNAIL_CONSTRAINT, 'fullsize_constraint' => Omeka_Form_Install::DEFAULT_FULLSIZE_CONSTRAINT, + 'recent_admin' => Omeka_Form_Install::DEFAULT_RECENT_ADMIN, 'per_page_admin' => Omeka_Form_Install::DEFAULT_PER_PAGE_ADMIN, 'per_page_public' => Omeka_Form_Install::DEFAULT_PER_PAGE_PUBLIC, 'show_empty_elements' => Omeka_Form_Install::DEFAULT_SHOW_EMPTY_ELEMENTS, diff --git a/application/models/Mixin/Tag.php b/application/models/Mixin/Tag.php index 4c736fd681..dcfaec5d43 100644 --- a/application/models/Mixin/Tag.php +++ b/application/models/Mixin/Tag.php @@ -139,6 +139,14 @@ public function deleteTags($tags, $delimiter = null) $removed[] = $this->_tagTable->find($tagging->tag_id); $tagging->delete(); } + + $db = $this->_record->getDb(); + foreach ($tags as $tag) { + $count = $this->_joinTable->count(array('tag' => $tag)); + if ($count == 0) { + $db->delete($db->Tags, array('name = ?' => $tag)); + } + } $nameForHook = strtolower($this->_type); fire_plugin_hook("remove_{$nameForHook}_tag", array('record' => $this->_record, 'removed' => $removed)); diff --git a/application/models/Table/Tag.php b/application/models/Table/Tag.php index 71b95e7bba..049e2d9e7e 100644 --- a/application/models/Table/Tag.php +++ b/application/models/Table/Tag.php @@ -191,4 +191,21 @@ public function findTagNamesLike($partialName, $limit = 10) $tags = $db->fetchCol($sql, array($partialName . '%')); return $tags; } + + public function mergeTags($oldTagId, $newTagId, $recordType = '') + { + if ($recordType != '') $recordType = " AND record_type = '" . $recordType . "'"; + + $db = $this->getDb(); + $sql = "UPDATE $db->RecordsTag SET tag_id = $newTagId, time = CURRENT_TIMESTAMP WHERE tag_id = $oldTagId" . $recordType . " AND record_id NOT IN (SELECT record_id FROM (SELECT DISTINCT record_id FROM $db->RecordsTag WHERE tag_id = $newTagId) AS tmptable)"; + $db->query($sql); + $sql = "DELETE FROM $db->RecordsTag WHERE tag_id = $oldTagId" . $recordType; + $db->query($sql); + $sql = "DELETE FROM $db->Tag WHERE id = $oldTagId"; + $db->query($sql); + + $sql = "SELECT COUNT(id) AS tagCount FROM $db->RecordsTag WHERE tag_id = $newTagId" . $recordType; + $tagCount = $db->fetchOne($sql); + return $tagCount; + } } diff --git a/application/views/helpers/CollectionSearchFilters.php b/application/views/helpers/CollectionSearchFilters.php new file mode 100644 index 0000000000..dac7c81eab --- /dev/null +++ b/application/views/helpers/CollectionSearchFilters.php @@ -0,0 +1,70 @@ +getRequest(); + $requestArray = $request->getParams(); + } else { + $requestArray = $params; + } + + $db = get_db(); + $displayArray = array(); + foreach ($requestArray as $key => $value) { + if ($value != null) { + $filter = ucfirst($key); + $displayValue = null; + switch ($key) { + case 'public': + case 'featured': + $displayValue = ($value == 1 ? __('Yes') : $displayValue = __('No')); + break; + } + if ($displayValue) { + $displayArray[$filter] = $displayValue; + } + } + } + + $displayArray = apply_filters('collection_search_filters', $displayArray, array('request_array' => $requestArray)); + + $html = ''; + if (!empty($displayArray) || !empty($advancedArray)) { + $html .= '
'; + $html .= '
    '; + foreach ($displayArray as $name => $query) { + $class = html_escape(strtolower(str_replace(' ', '-', $name))); + $html .= '
  • ' . html_escape(__($name)) . ': ' . html_escape($query) . '
  • '; + } + if (!empty($advancedArray)) { + foreach ($advancedArray as $j => $advanced) { + $html .= '
  • ' . html_escape($advanced) . '
  • '; + } + } + $html .= '
'; + $html .= '
'; + } + return $html; + } +} \ No newline at end of file diff --git a/application/views/scripts/collections/browse.php b/application/views/scripts/collections/browse.php index 652d5afbbd..b7bb18de2d 100644 --- a/application/views/scripts/collections/browse.php +++ b/application/views/scripts/collections/browse.php @@ -4,8 +4,11 @@ ?>

+ + 0): ?> +
+ +
diff --git a/application/views/scripts/items/tags.php b/application/views/scripts/items/tags.php index 5d9e27f96a..c27383d9a0 100644 --- a/application/views/scripts/items/tags.php +++ b/application/views/scripts/items/tags.php @@ -1,5 +1,5 @@ $pageTitle, 'bodyclass' => 'items tags')); ?>