Sorting By Dublin Core Date Field

Can you sort by more than just a year in the date field? I plan to use something like:

<?php
    echo link_to_browse_items('Sorted by Date', array('sort_field' => 'Dublin Core,Date'));
?>

Some of our dates are specific like September 19, 1950 and others just have a four digit year. Is there a format that would allow sorting of both types of dates? dd/mm/yyyy or dd.mm.yy?

The sorting is very literal, it uses bog-standard alphanumeric sorting order. (This applies only for textual date metadata, like the Dublin Core date field. The "modified" and "added" dates sort correctly.)

If you want the sort to work in some kind of reasonable manner, your best bet is to standardize on a particular format.

A format like YYYY-mm-dd will sort correctly for all those cases, including ones where months or days are excluded.

Thanks.

A couple follow-up questions. Is there a way to have it entered in the YYYY-mm-dd format, but have it display in the September 21, 1951 format? My initial thought is to have two date fields, one that displays the right format, the other hidden field stores the sortable date format. Then the link I'd create would use the second field. However, I was wondering if there was a php file I could edit that would do this automatically.

Also we have some dates that we are not sure of the exact date so we have been using saying circa 1947. Is there a way to include this in the sortable list of dates? Would it be better for sorting purposes to have 1947 circa?

For sorting purposes, having the "date" part come first is important, so something like 1947 (circa) or 1947c would be better.

As for the display, PHP and Zend both have lots of functions for taking date strings and printing them in different formats, but those are mostly geared toward working well when you want all dates to look the same, not as much when some dates need to omit things like the month or day.

Still, as long as you stick to a format, it's certainly possible to do this. The PHP DateTime class should be able to do what you're asking:

$date = new DateTime('1951-09-21');
echo $date->format('F j, Y');

That code takes a YYYY-mm-dd formatted date, and outputs "September 21, 1951." The only thing left out of there is some logic to use a different format if the input date doesn't specify the month or day.

Thanks, I now have it working with a few modifications to my show.php file. I no longer have the date set to display with the show_item_metadata(), instead I use item() helper function:

<div class="element">
<h3>Date:&nbsp;</h3>
<div class="element-text">
<?php $date=item('Dublin Core', 'Date');
if ((strlen($date))==10){
$newdate=new DateTime(item('Dublin Core', 'Date'));
echo $newdate->format('F j, Y');}
elseif ((strlen($date))==7){
$newdate=new DateTime(item('Dublin Core', 'Date'));
echo $newdate->format('F, Y');}
else{
echo $date;
}
?>

The code is a little rough right now, but it works. Basically the conditional statements use strlen to check to see if its YYYY-MM-DD or YYYY-MM. If it's not then it just displays the date as it was entered.

I've gone through and updated all of my dates to fit the YYYY-MM-DD format. For dates that have circa, I've changed them to YYYY (circa). I've adjusted the code in my previous post to also display the circa dates as "circa YYYY". So in my show.php file I have the following:

<div class="element">
<h3>Date:&nbsp;</h3>
<div class="element-text">
<?php $date=item('Dublin Core', 'Date');
if ((strlen($date)==10)&&(strstr($date,'-'))){
$newdate=new DateTime(item('Dublin Core', 'Date'));
echo $newdate->format('F j, Y');}
elseif ((strlen($date)==7)&&(strstr($date,'-'))){
$newdate=new DateTime(item('Dublin Core', 'Date'));
echo $newdate->format('F, Y');}
elseif (stristr($date,'circa')){
$newdate='circa ';
$newdate.=substr($date,0,4);
echo $newdate;}
else{
echo $date;
}
?>
</div>
</div>

Then in my browse.php file, I am using browse_headings() to generate a Sort by Date link.

<?php $browseHeadings['Sort by Date'] = 'Dublin Core,Date';
echo browse_headings($browseHeadings); ?>

Now I'm trying to incorporate this into my custom next previous links. Is there a way to get the sort direction information like there is to get the search information like ?search='.$_GET['search']?

Thanks again.

The sorting information is in the sort_field and sort_dir keys of the $_GET array.

I’ve got the sort by date and my custom next previous working, but I’ve noticed a little glitch when using the sort by date on all the items in our collection.
Here’s the modifications I have made to the custom next previous function :

function custom_next_previous()
{
$sortfield=$_GET['sort_field'];
$current = item('id');
$sortdir=$_GET['sort_dir'];
if (($search = $_GET['search'])||($sortfield=='Dublin Core,Date')) {
	if($sortfield=='Dublin Core,Date' && isset($search)){
	   $list = get_items(array('search'=>$search, 'sort_field'=>$sortfield, 'sort_dir'=>$sortdir),total_results());}
     else if($sortfield=='Dublin Core,Date' && empty($search)){
        $list = get_items(array('sort_dir'=>$sortdir,'sort_field'=>$sortfield),total_results());}
else{
$list=get_items(array('search'=>$search),total_results());}

foreach ($list as &$value) {
            $itemIds[] = $value->id;
        }

The rest follows from the recipe. What I've noticed is that when I sort my entire collection so that it's sort_field=Dublin Core, Date & sort_dir=d the first record in my browse list has a previous button. I added a print_r($itemIds) statement after the foreach, and it seems like the first item in my browse results is actually the 10th item in the arrary $itemIds. When I switch the code above so that the sort_field ="Dublin Core, Title" this doesn't happen, the first item in my browse list is the first item in the array $itemIds.

Any thoughts as to why this might be happening?

I'm not sure what the exact problem is here, but this code just generally seems more complicated than it needs to be.

It's not clear to me why your code needs to be doing anything different based on what the sort field is.

To build up the array of arguments for get_items, it will probably be easier to just have a set of simple checks up front:

$getItemsParams = array();
if (isset($_GET['search'])) {
    $getItemsParams = $_GET['search'];
}
if (isset($_GET['sort_field'])) {
    $getItemsParams = $_GET['sort_field'];
}
if (isset($_GET['sort_dir'])) {
    $getItemsParams = $_GET['sort_dir'];
}

then just check to see if $getItemsParams has anything in it (if ($getItemsParams) {) to decide whether you need to call get_items or whether you can just do the "standard" next/previous links.

Thanks, I've simplified my code based on your suggestion, and I added keys for the $getItemsParams array.

$getItemsParams = array();
if (isset($_GET['search'])) {
    $getItemsParams['search'] = $_GET['search'];
}
if (isset($_GET['sort_field'])) {
    $getItemsParams['sort_field'] = $_GET['sort_field'];
}
if (isset($_GET['sort_dir'])) {
    $getItemsParams['sort_dir'] = $_GET['sort_dir'];
}

if (isset($getItemsParams)){
$current = item('id');
$list=get_items($getItemsParams,total_results());

However it still has the glitch when sorting the entire collection sort_field=Dublin Core, Date and sort_dir=d. The first record in my browse results has a previous and next link, and it's still the 10th item in the $itemIds array. The last record of the first page of results only has a next link, it's the 1st item in the $itemIds array.

This issue does not occur if I run a search and then set the sort_field to dublin core, date and sort_dir to d. Nor does it occur if I set the sort_field to another field like dublin core title. In those cases, the first item in the browse results is also the first item in the $itemIds array.

Yes, good catch, the keys were missing from my code. Not to dwell on things other than your particular problem too much, but your check of isset($getItemsParams) won't actually work (it'll always return true), since just the $getItemsParams = array(); at the top is enough to make the variable "set." Dropping the isset in that check should make it work correctly.

As for the problem you're having with an erroneous previous link, it sort of sounds like the sort_dir parameter's not making it through correctly. Dropping that parameter somewhere between your browse page and show page would give this result for any browse with a sort_dir of "d".

The code you posted here looks fine (except for the isset, but that wouldn't be causing this problem). Can you post the URL of the browse and show pages for the query that's causing the problem? In particular, I'd be interested to see the query strings.

Thanks, I've removed the isset. Unfortunately our site is currently behind a university login, but I'll try to post what our site looks like and some of the code this weekend. Otherwise, I think I've made some progress.

I copied the $itemIds array that was generated by the date sort_dir=a and the sort_dir=d into a spreadsheet. I then reversed the direction of the sort_dir=d list. I expected it to match up with the sort_dir=a array. It was close but there were spots where it would be off.

For example here are the first dozen or so of the results of sort_a and sort_d(which was reversed)

sort_dir=a      sort_dir=d(reversed)
[0] => 931	[1690]=>931
[1] => 2351	[1689]=>2345
[2] => 2350	[1688]=>2346
[3] => 2349	[1687]=>2347
[4] => 2348	[1686]=>2348
[5] => 2347	[1685]=>2349
[6] => 2346	[1684]=>2350
[7] => 2345	[1683]=>2351
[8] => 909	[1682]=>909
[9] => 1885	[1681]=>1885
[10] => 1886	[1680]=>1886
[11] => 1887	[1679]=>1887
[12] => 12	[1678]=>1888
[13] => 1888	[1677]=>12

You can see the item ids are close but don't always match up exactly. I'm thinking this occurs because some of our record have the same date or same entry like No Date. There might be another field that the sort uses to arrange these items when the dates are the same. Still not sure why this puts the tenth item in the array as the first item in the browse results for the sort_dir=d, but I think I'm on the right track.

I'm sorry, I should have clarified.

I just wanted to see the URLs that were getting generated by your other code (the code that creates the links from the browse page) to make sure the parameters are being passed along correctly.

All I was interested in was the URLs, not the pages themselves (really just the query strings even, you can leave off the domain part).

I use the following code to generate my links from the browse to show pages:

<?php if($search=$_GET['search']||$sort=$_GET['sort_field']):
$searchlink = item_uri().'?'.$_SERVER['QUERY_STRING'];
echo '<h2><a href="'.$searchlink.'">'.item('Dublin Core','Title').'</a></h2>

So when I click the sort by date link twice so the sort_dir=d the url on my browse page is "omeka/items?sort_field=Dublin+Core%2CDate&sort_dir=d" and the url for my item show page is "omeka/items/show/2316?sort_field=Dublin+Core%2CDate&sort_dir=d".

Okay...

This doesn't really make sense. sort_dir=a and sort_dir=d seem to give you (roughly) reversed lists, which is what should happen to make things work correctly.

Just to be clear, when you say you're sorting all the items in the "collection," you're referring to your Omeka site as a whole, not a specific Omeka collection, right? Your custom next/previous code doesn't handle filters other than simple search.

Does the sort_dir=d list generated by get_items on the show page match up with the order the items appear on the browse page (also with sort_dir=d)? (The easiest way to see the item IDs on the browse page would be to just hover over the links to the items.)

Right I am referring to my site as a whole when I say sorting all the items in the collection.

Here's a list of the sort_dir=d list on my show page, and a list of the first twenty items that show up on the first two browse pages when sort_dir=d.

show.php array          Browse item numbers
[0] => 5 		2316
[1] => 41 		2164
[2] => 123 		1111
[3] => 1111 		888
[4] => 295 		417
[5] => 416 		416
[6] => 417 		295
[7] => 888 		123
[8] => 2164 		41
[9] => 2316 		5
[10] => 13 		13
[11] => 2023 		2023
[12] => 1090 		1090
[13] => 2795 		2798
[14] => 2798 		2797
[15] => 2797 		2796
[16] => 2796 		2795
[17] => 2794 		2794
[18] => 2793 		2793
[19] => 2792		2792

I also thought maybe it might be due to the size of the collection, since it works when running a search and a sort by date. So I tried a simple search that got 1690 of the 1691 items that are marked public and set the sort_dir=d. I was able to use the custom next/previous.

You might be able to get to the bottom of this by turning on SQL logging, which you do by setting log.sql to true in application/config/config.ini.

This will result in lots of output to your Omeka error log, since it will log every SQL statement Omeka runs (and it runs quite a few). You should be able to track down the queries involved on the browse and show pages here pretty simply, they'll both be fairly large queries starting with something like SELECT FROM omeka_items AS i...

Thanks, I've enabled SQL logging, and I've copied a few versions of the error log to look at. Basically I performed a sort, then copied an error log, uploaded a blank error log, and then performed another action, and copied the new error log.

Not entirely sure what I'm going to be looking for. I have error logs from the following actions:

Sort_d of all items in the collection
Sort_d of items in a search
Click on first item in both of the prior actions

I'll try to look through these tomorrow, to see if there's anything going on. You weren't kidding that Omeka runs quite a few SQL statements.

It appears the issue is related to having the same entities in the date field. Originally there were about 150 items in our collection that had "No Date" in the date field. When you sorted the items by date, these items were bunched together causing the problem. We went back through these items and added circa dates to the images, so they are distributed more evenly throughout our entire collection. When I tried to sort them after applying these changes, the problem was occurring while sort=a instead of sort=d. The first item of the browse results had a next and previous link; the second item had only a next link. Both of these items had the exact same date 1870 (circa). So I changed one item to 1871 (circa), and now the first item has a next link only. It seems there is some extra level of sorting that occurs besides just the date if the items happen to have the same date. Previously I tried this with Dublin Core, Title, and was not having the same issue. It seems that's because no two titles in our collection are the same. However, I was able to replicate the problem with Dublin Core, Subject. This field also has a lot of entries that are the same. I'm guessing that it doesn't happen when doing this within a simple search because the search terms strictly control how items will be ordered if they have the same date.

As of right now the beginning and ends of all of our items work with the sort by date. There might be some discrepancies between the browse order and my custom next/previous links in the middle of all the results, but I don't see the user really noticing that.

Thanks again.