Extension talk:Cargo/Archive November to December 2016

From mediawiki.org

Referential integrity?

Does Cargo enable me to restrict the contents of a column to the values contained in another table?

The desired end result is a form where the values in that column are not free-entry but rather selected from a drop down list that is populated from another table.

This is really a Page Forms question, but yes - in the form definition, you can have something like "{{{field|Author|input type=dropdown|cargo table=Authors|cargo field=_pageName}}}". Yaron Koren (talk) 02:05, 14 November 2016 (UTC)Reply

Formatting of floating-point numbers

Hi Yaron,

We've come across a bit of an oddity when displaying the results of queries that contain float values that happen to be integers: the number of decimal places shown in the formatted number depends on the length of the number. For example, 6 is formatted correctly as "6", whereas 24 becomes "24.0", 100 becomes "100.00", and 1000 becomes "1,000.000".

I think the culprit is line 168 of CargoQueryDisplay:

 $numDecimalPlaces = strlen( $value ) - strrpos( $value, '.' ) - 1

... which needs a special case for when '.' isn't found.

On a related note, it would be nice to be able to right-align numerical columns by default. The CSS classes based on the field names make this possible, but you have to handle each numerical field separately. If you could use CSS classes to indicate the data type, this would be easier. Also, I can't see a way to do this with dynamic tables, as there don't seem to be any classes defined there. Many thanks. Paul T (talk) 20:00, 1 November 2016 (UTC)Reply

That's true... what do you think a good default number of decimal places would be - 0? 1? The CSS is also a pretty good idea. I don't think it's possible within dynamic tables, i.e. the DataTables JS library, though, unfortunately. Although numbers in dynamic tables are right-aligned automatically, no? Yaron Koren (talk) 03:19, 2 November 2016 (UTC)Reply
Apologies for the slow response. The patch you've done to avoid adding decimals works nicely. I suspect use cases for floats vary so much that there's no sensible default for the number of decimal places. A nice feature (but not one that we really need) would be to be able to specify a default display format in the Cargo table definition (in a similar manner to how the "link text" and "hidden" attributes are dealt with).
On the CSS issue, I see that the DataTables javascript library does have a "columns.className" option. It also has an order option that it might be handy to expose: at present, it seems to sort the data by the first field, undoing any ordering specified in the cargo_query call. Paul T (talk) 13:15, 16 November 2016 (UTC)Reply
The "order by" problem has now been fixed, at least. Yaron Koren (talk) 04:11, 5 December 2016 (UTC)Reply

Sparse matrix

Is it possible to implement a list field with named elements to store a sparse matrix? May be, is there any other way? --StasR (talk) 13:39, 2 November 2016 (UTC)Reply

Yes - what's the extra challenge with a sparse matrix? Yaron Koren (talk) 13:52, 2 November 2016 (UTC)Reply
For each row of the matrix need to store a plurality of pairs of "index (key) - value" and I need to be able to get the value for the key. Of course, I can myself organize a separate table, but it will require a lot of calls cargo_store. --StasR (talk) 14:13, 2 November 2016 (UTC)Reply
Oh, I see - you want to store a sparse matrix within each page. If so, what about a multiple-instance template, where the template contains "key" and "value" fields? Yaron Koren (talk) 14:27, 2 November 2016 (UTC)Reply
The tempate call looks like this: {{ tpt | fixField1=val1 | fixField2=val2 | varField25=val3 | varField999=val4 }}. It is logical to convert it into a function {{#cargo_store... | fixField1="val1" | fixField2="val2" | listField = "varField25"="val3","varField999"="val4"}}. And you save _rowID, _key, _value in the separate table. --StasR (talk) 15:29, 2 November 2016 (UTC)Reply
Alright. Is your problem solved now? Yaron Koren (talk) 16:09, 2 November 2016 (UTC)Reply
Now I use an separate no-sparse table. It is useful for experiments, but it is bad for real work (especially because the number of columns will grow with time). --StasR (talk) 16:25, 2 November 2016 (UTC)Reply
If so, what about a multiple-instance template, where the template contains "key" and "value" fields? — Perhaps I did not understand exactly what you advise :-( --StasR (talk) 16:31, 2 November 2016 (UTC)Reply
Do you know what multiple-instance templates are? Yaron Koren (talk) 17:09, 2 November 2016 (UTC)Reply
I found it in PageForms description. If I understand correctly, this is multiple cargo_store calls. This is true? --StasR (talk) 17:54, 2 November 2016 (UTC)Reply
Yes. Yaron Koren (talk) 18:37, 2 November 2016 (UTC)Reply
It is too prodigally for my task. I fear timeout. --StasR (talk) 18:43, 2 November 2016 (UTC)Reply

How many key/value pairs could a single page have? I thought you said it was "sparse". :) Yaron Koren (talk) 03:12, 3 November 2016 (UTC)Reply

One page is shaping up to 200-300 main table records. Each main table record usually includes 10-20 pairs. --StasR (talk) 07:42, 3 November 2016 (UTC)Reply
Okay, now I don't understand again... a page holds main table records, which themselves hold key/value pairs? That sounds like you basically want to store a three-dimensional array of data on every page. What's a main table record? Yaron Koren (talk) 13:10, 3 November 2016 (UTC)Reply

Fatal_exception_of_type_MWException_on_RunQuery_Template

Hi, was there any resolution on this issue?

Fatal_exception_of_type_MWException_on_RunQuery_Template

We are finding the same problem - CONCAT is breaking when used in a query form, but works otherwise. We're using Semantic Forms 3.7 and Cargo 1.0.1. --Bgrenon (talk) 19:12, 4 November 2016 (UTC)Reply

Try upgrading Cargo. You might as well upgrade Semantic Forms while you're at it, i.e. switch to Page Forms. Yaron Koren (talk) 20:23, 4 November 2016 (UTC)Reply
Upgrading Cargo seemed to work. (Haven't tried upgrading to Page forms yet). Thanks! --Bgrenon (talk) 10:44, 10 November 2016 (UTC)Reply

Problem with the Cargo Query Calendar format

Hi

I've been trying to get this to work with Cargo 1.1.1 and MW1.26.4 and encountered a few problems.

The page call I'm using is

{{#cargo_query:
tables=Articles
|fields=_pageName,Description,Event_Start_Date_Time
|where=DATEDIFF(Event_Start_Date_Time,NOW()) >= -30
|format=calendar
|color=red
}}

Firstly CargoExport was failing with:

A database query error has occurred. This may indicate a bug in the software.
 
Query:
SELECT `_pageName`,`Event_Start_Date_Time` AS `Event Start Date   Time`,`Event_Start_Date_Time__precision` AS `Event Start Date Time__precision` FROM `cargo__Articles` WHERE DATEDIFF(Event_Start_Date_Time,NOW()) >= -30 AND ((Event_Start_Date_Time >= '2016-10-30' AND Event_Start_Date_Time <= '2016-12-11)) ORDER BY `_pageName` LIMIT 100
Function: CargoSQLQuery::run
Error: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2016-12-11)) ORDER BY `_pageName` LIMIT 100' at line 1 (localhost)

I managed to fix this in function displayCalendarData() by adding an apostrophe before the final ')' on the following line:

$where .= "($dateField >= '$datesLowerLimit' AND $dateField <= '$datesUpperLimit)";

The calendar was still not displaying events and gave the following warning:

Notice: Undefined index: Event_Start_Date_Time__precision in /var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/extensions/Cargo/specials/CargoExport.php on line 131

I managed to fix this by removing the str_replace clause from the following line in the same function:

$startDatePrecisionField = str_replace( ' ', '_', $startDateField ) . '__precision';

I am also having problems getting the Calendar Format to recognise the color parameter although I've yet to work out this one.

Finally I have tried to use an alternative Cargo field for the calendar event title by using the following field parameter.

fields=_pageName=Title,Description,Event_Start_Date_Time

This works if I use the default table format but not within the Calendar format. I'd like to do this because I'm using Semantic Title where the Cargo field Title is the semantic title for the page.

I wondered if I might have been doing something wrong to cause the above issues or whether the fixes I've made are OK?

Many thanks

Duncan, 11 Nov 2016

Hi

I've now had a look at the problem displaying colours in the calendar format and found a possible fix for that too. In CargoCalendarFormat.php function queryAndDisplay there is a block of code:

			if ( $querySpecificParams != null ) {
				if ( array_key_exists( 'color', $querySpecificParams[$i] ) ) {
					$queryParams['color'][] = $querySpecificParams[$i]['color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color'][] = 'red';
				}

If this is changed to the following then colours display OK:

			if ( $displayParams != null ) {
				if ( array_key_exists( 'color', $displayParams ) ) {
					$queryParams['color'][] = $displayParams['color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color'][] = '';
				}

As before I'm not really sure I understand this code fully so this change may mess up something else. Would you advise?

Kind regards

Duncan 12 Nov 2016

Sorry about all the problems you ran into!
  • The missing-parenthesis problem: I actually discovered this bug about a week ago, and checked in a fix for it then (it was the same fix you found).
  • Problem with underscores in date fields: thanks for that fix; I'll probably check it in soon.
  • Alternative title field: there's a way to do this, and it's actually mentioned in the documentation, though it's easy to miss. Instead of an "=Title" alias, I think you just need to set the alias to be "=name".
  • The multiple-colors problem: I have no idea where that 'red' value came from; it's not now, and doesn't look like it ever was, in the Cargo code. Could it be that you changed that line yourself during testing? Anyway, this, at least, looks like a non-bug. Yaron Koren (talk) 02:22, 14 November 2016 (UTC)Reply


Hi Yaron
Thank you for your responses and fixes. You do a fantastic job producing all this great code, so I'm glad if I can help identify the occasional minor problems. On the colours question, you are right the 'red' was part of my testing trying to track down how colors were being set, although I am not sure this effects the problem I was encountering. What my testing seemed to show is that the colour parameter is being passed to the function as part of the $displayParams variable rather than in the $querySpecificParams array variable. As a result, the following line never found the colour parameter being passed from the cargo query:
				if ( array_key_exists( 'color', $querySpecificParams[$i] ) ) {
					$queryParams['color'][] = $querySpecificParams[$i]['color'];
				} else ...
When I changed that line to the following it seems to pick up the colour OK:
				if ( array_key_exists( 'color', $displayParams ) ) {
					$queryParams['color'][] = $displayParams['color'];
				} else ...
Is it possible I've inadvertently affected how the color parameter is passed to the queryAndDisplay function?.
Many thanks
Duncan 15 Nov 2016
Oh, I didn't notice the rest of the code changes. Could it be that you're putting the 'color' parameter in the wrong place in the #cargo_compound_query call? It should be within each "sub-query". Yaron Koren (talk) 14:39, 16 November 2016 (UTC)Reply
Ah now I see where I may be going wrong. Perhaps if I explain what I'm trying to do maybe you will tell me if it is possible?
What I'd like is to display pages from an Articles table on the calendar. Each Article has an Event Type field that looks up on a separate Event Types table. Each Event Type has a Colour field associated with it.
By joining the Articles and Event Types table, I hope to find the colour associated with each and then have the Calendar format use this to select the background colour for each calendar entry. Originally I assumed I wouldn't need to use Cargo's compound query which would leave me with a simple query such as:
{{#cargo_query:
tables=Articles,Event_types
|join on=Articles.Event_Type=Event_types._pageName
|fields=Articles._pageName,Articles.Description,Articles.Event_Start_Date_Time,Articles.Event_End_Date_Time,Event_types.Title,Event_types.Colour
|where=DATEDIFF(Articles.Event_Start_Date_Time,NOW()) >= -30
|format=calendar
|color=Event_types.Colour
}}
From what you say above, the Calendar format requires you use Cargo's compound query to use the colour parameter. I have tried this using a literal value for the colour parameter and this does indeed work . However, if I try to use a variable, such as Event_types.Colour which changes for each calendar entry, this doesn't seem to work. For example:
{{#cargo_compound_query:
tables=Articles,Event_types
;join on=Articles.Event_Type=Event_types._pageName
;fields=Articles._pageName,Articles.Description,Articles.Event_Start_Date_Time,Articles.Event_End_Date_Time,Event_types.Title,Event_types.Colour
;where=DATEDIFF(Articles.Event_Start_Date_Time,NOW()) >= -30
;color=Event_types.Colour
|format=calendar
}}
I wonder if what I am trying to do is possible and, if so, where I'm going wrong? I was able to do this when I used SMW as the data source but I know quite a lot changed in the query function for Cargo. It looks like it might be possible if I do a compound query on the same table to select each event type and set its colour using a literal value, but this seems a bit inefficient and probably makes maintenance more complicated.
If it is not possible to use a field variable to set the background colour, is this a feature you might consider for the future? It would also be useful to send other parameters to the calendar for each event such as the end date and time so that it displays events that span several hours or days.
Many thanks
Duncan 17 Nov 2016
Ah, now it makes sense. No, you can't get the color value from the database. I know Semantic Result Formats has such a feature, with the "Has color" special property, but I decided against it for Cargo, because it seemed like the query was the more natural place to set that information. If you want the same page to be displayed with a different color in two different calendars, and the color information is set in the page itself, it's awkward (though possible). But I'm curious - in what way do you think setting the color info in the query is less efficient? Yaron Koren (talk) 14:53, 17 November 2016 (UTC)Reply
Thanks Yaron, my thinking is this. Say I have two types of event - Show and Race. I want the calendar events with type Show to have a green background and those of type Race to be red. I imagine (although this is just speculation as I haven't tried it yet) that the compound query would look like this?
{{#cargo_compound_query:
tables=Articles,Event_types
;join on=Articles.Event_Type=Event_types._pageName
;fields=Articles._pageName,Articles.Description,Articles.Event_Start_Date_Time,Articles.Event_End_Date_Time,Event_types.Title,Event_types.Colour
;where=Event_types.Title=Show
;color=green
|tables=Articles,Event_types
;join on=Articles.Event_Type=Event_types._pageName
;fields=Articles._pageName,Articles.Description,Articles.Event_Start_Date_Time,Articles.Event_End_Date_Time,Event_types.Title,Event_types.Colour
;where=Event_types.Title=Race
;color=red
|format=calendar
}}
The reason I supposed this to be inefficient was because I thought it may have to perform the join and then select the right type of articles twice, once for each parameter of the compound query. If it had been possible to pick up the colour for each calendar event from the join, then I had imagined I would only have to perform the join once and there would be no need to select a subset of the records for each event type. You've probably realised I'm a bit of a novice so apologies if I've go the wrong end of the stick but I'd be interested to know how this works.
Kind regards
Duncan 17 Nov 2016
Hi again. I now tested a version of the compound query that tests for the colour of the event type and sets the background colour as follows. This does achieve the effect I want, although I don't really have enough data to tell about its efficiency:
{{#cargo_compound_query:
tables=Events,Event_types
;join on=Events.Event_Type=Event_types._pageName
;fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_Type,Event_types.Colour
;where=Event_types.Colour="brown"
;color=brown
|tables=Events,Event_types
;join on=Events.Event_Type=Event_types._pageName
;fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_Type,Event_types.Colour
;where=Event_types.Colour="orange"
;color=orange
|format=calendar
}}
I also thought about the use case that you gave whereby one might want to display the same events with different colours on different calendars. This might still be possible in the same way as it is now whilst still allowing the query to pick up a variable (database value) if one was set. This might be done if the code could distinguish between whether a literal or variable database value was passed with the Color parameter. If the Color parameter was a literal it could function as now and apply that value to each calendar event. On the other hand, if the Color parameter was a variable database value that might be used instead for each calendar event. That way one might achieve both use cases depending on the type of value passed in the Color parameter.
As mentioned I am out of my depth here but if you pointed me to the place where the programme sets the values for each of the calendar event entries I could see if I can get this working, if you think this might be a useful feature?
Many thanks, Duncan 17 Nov 2016
That's true, this approach of getting the color from the database would indeed be more efficient. And I think your first instinct was right, that this sort of thing should be handled via #cargo_query and not #cargo_compound_query - since it's not a compound query at all. The only thing I would change is that there should be a new parameter for this, probably named "color field=", to avoid confusion with "color=", which would keep only taking hardcoded colors. It does sound like a possibly useful feature, and if you want to have a go at creating a patch for it, feel free - I'll add it in to the code. Yaron Koren (talk) 20:02, 17 November 2016 (UTC)Reply
Thanks Yaron. It's taken me a while to work this out but it's been an interesting journey. I'm not sure I know how to create a patch so I've just included the code changes below. I've tested them and they seem to work OK. Also the Color parameter still seems to function as before. However as mentioned I am a novice so you might want to check I haven't done anything daft!
I've also enabled cargo query with calendar format to display events that span more than one day correctly if an end date is supplied (see query example below). And to round things off I've enabled the text colour to be specified (also see example below). This was necessary in case one used light background colours to ensure sufficient contrast for the text.
I'm hoping you will be able to adopt these changes so I can feel I've given somthing back to the Cargo community!
This is the updated version of the queryAndDisplay function in CargoCalendarFormat.php
	function queryAndDisplay( $sqlQueries, $displayParams, $querySpecificParams = null ) {
		$this->mOutput->addModules( 'ext.cargo.calendar' );
		$ce = SpecialPage::getTitleFor( 'CargoExport' );
		$queryParams = $this->sqlQueriesToQueryParams( $sqlQueries );
		$queryParams['format'] = 'fullcalendar';
		$queryParams['color'] = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			if ( $querySpecificParams != null ) {
				if ( array_key_exists( 'color', $querySpecificParams[$i] ) ) {
					$queryParams['color'][] = $querySpecificParams[$i]['color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'color field', $displayParams ) ) {
					$queryParams['color field'][] = $displayParams['color field'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color field'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'text color', $displayParams ) ) {
					$queryParams['text color'][] = $displayParams['text color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['text color'][] = '';
				}
			}
		}
		if ( array_key_exists( 'width', $displayParams ) ) {
			$width = $displayParams['width'];
			// Add on "px", if no unit is defined.
			if ( is_numeric( $width ) ) {
				$width .= "px";
			}
		} else {
			$width = "100%";
		}

		$attrs = array(
			'class' => 'cargoCalendar',
			'dataurl' => $ce->getFullURL( $queryParams ),
			'style' => "width: $width"
		);

		if ( array_key_exists( 'view', $displayParams ) ) {
			$view = $displayParams['view'];
			// Enable simpler view names.
			if ( $view == 'day' ) {
				$view = 'basicDay';
			} elseif ( $view == 'week' ) {
				$view = 'basicWeek';
			}
			$attrs['startview'] = $view;
		} else {
			$attrs['startview'] = 'month';
		}
		if ( array_key_exists( 'start date', $displayParams ) ) {
			$attrs['startdate'] = $displayParams['start date'];
		}
		$text = Html::rawElement( 'div', $attrs, '' );

		return $text;
	}

}
This is the updated version of the displayCalendarDatafunction in CargoExport.php
	/**
	 * Used for calendar format
	 */
	function displayCalendarData( $sqlQueries ) {
		$req = $this->getRequest();

		$colorArray = $req->getArray( 'color' );
		$textColorArray = $req->getArray( 'text_color' );
		$colorFieldArray = $req->getArray( 'color_field' );

		$datesLowerLimit = $req->getVal( 'start' );
		$datesUpperLimit = $req->getVal( 'end' );

		$displayedArray = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			foreach( $sqlQuery->mFieldStringAliases as $fieldName => $fieldAlias ) {
				if ( $fieldName == $colorFieldArray[0] ) {
					$colorFieldName = $fieldAlias ;
				}
			}

			$dateFieldRealNames = array();
			$dateFieldAliases = array();
			foreach( $sqlQuery->mFieldDescriptions as $alias => $description ) {
				if ( $description->mType == 'Date' || $description->mType == 'Datetime' ) {
					$dateFieldAliases[] = $alias;
					$realFieldName = $sqlQuery->mAliasedFieldNames[$alias];
					$dateFieldRealNames[] = $realFieldName;
				}
			}
			$where = $sqlQuery->mWhereStr;
			if ( $where != '' ) {
				$where .= " AND ";
			}
			$where .= "(";
			foreach ( $dateFieldRealNames as $j => $dateField ) {
				if ( $j > 0 ) {
					$where .= " OR ";
				}
				$where .= "($dateField >= '$datesLowerLimit' AND $dateField <= '$datesUpperLimit')";
			}
			$where .= ")";
			$sqlQuery->mWhereStr = $where;

			$queryResults = $sqlQuery->run();
			foreach ( $queryResults as $queryResult ) {
				if ( array_key_exists( 'name', $queryResult ) ) {
					$eventTitle = $queryResult['name'];
				} else {
					$eventTitle = reset( $queryResult );
				}
				$title = Title::newFromText( $queryResult['_pageName'] );
				$startDateField = $dateFieldAliases[0];
				$startDate = $queryResult[$startDateField];
				$startDatePrecisionField = $startDateField . '__precision';
				$startDatePrecision = $queryResult[$startDatePrecisionField];
				if ( array_key_exists( $colorFieldName , $queryResult ) ) {
					$eventColor = $queryResult[$colorFieldName];
				} else {
					$eventColor = $colorArray[$i];
				}

				$curEvent = array(
					// Get first field for the title - not
					// necessarily the page name.
					'title' => $eventTitle,
					'url' => $title->getLocalURL(),
					'start' => $queryResult[$dateFieldAliases[0]],
					'end' => $queryResult[$dateFieldAliases[1]],
					'color' => $eventColor,
					'textColor' => $textColorArray[$i]
				);
				if ( $startDatePrecision != CargoStore::DATE_AND_TIME ) {
					$curEvent['allDay'] = true;
				}

				$displayedArray[] = $curEvent;
			}
		}
		print json_encode( $displayedArray );
	}
This is an example of cargo query using the new capabilities
{{#cargo_query:
tables=Events,Event_types,Page_properties
|join on=Events.Event_Type=Event_types._pageName,Events._pageName=Page_properties._pageName
|fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_End_Date_Time,Events.Event_Type,Event_types.Colour,Page_properties.Title=name
|format=calendar
|color field=Event_types.Colour
|text color=blue
}}
Many thanks
Duncan 18 Nov 2016

Oh wow, great! I'll add this in. One question: the "text color" parameter certainly seems like it could have its uses, but, if "color field" is going to be used, shouldn't there really be a corresponding "text color field" parameter? Yaron Koren (talk) 16:17, 18 November 2016 (UTC)Reply

Seems logical - I'll look into it over the weekend :-) Duncan 18th November 2016
Ok, I think I've done this. Fortunately I hadn't had time to forget everything!
The code for the queryAndDisplay function in CargoCalendarFormat.php is:
	/**
	 *
	 * @param array $sqlQueries
	 * @param array $displayParams
	 * @param array $querySpecificParams
	 * @return string
	 */
	function queryAndDisplay( $sqlQueries, $displayParams, $querySpecificParams = null ) {
		$this->mOutput->addModules( 'ext.cargo.calendar' );
		$ce = SpecialPage::getTitleFor( 'CargoExport' );
		$queryParams = $this->sqlQueriesToQueryParams( $sqlQueries );
		$queryParams['format'] = 'fullcalendar';
		$queryParams['color'] = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			if ( $querySpecificParams != null ) {
				if ( array_key_exists( 'color', $querySpecificParams[$i] ) ) {
					$queryParams['color'][] = $querySpecificParams[$i]['color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'color field', $displayParams ) ) {
					$queryParams['color field'][] = $displayParams['color field'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color field'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'text color field', $displayParams ) ) {
					$queryParams['text color field'][] = $displayParams['text color field'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['text color field'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'text color', $displayParams ) ) {
					$queryParams['text color'][] = $displayParams['text color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['text color'][] = '';
				}
			}
		}
		if ( array_key_exists( 'width', $displayParams ) ) {
			$width = $displayParams['width'];
			// Add on "px", if no unit is defined.
			if ( is_numeric( $width ) ) {
				$width .= "px";
			}
		} else {
			$width = "100%";
		}

		$attrs = array(
			'class' => 'cargoCalendar',
			'dataurl' => $ce->getFullURL( $queryParams ),
			'style' => "width: $width"
		);

		if ( array_key_exists( 'view', $displayParams ) ) {
			$view = $displayParams['view'];
			// Enable simpler view names.
			if ( $view == 'day' ) {
				$view = 'basicDay';
			} elseif ( $view == 'week' ) {
				$view = 'basicWeek';
			}
			$attrs['startview'] = $view;
		} else {
			$attrs['startview'] = 'month';
		}
		if ( array_key_exists( 'start date', $displayParams ) ) {
			$attrs['startdate'] = $displayParams['start date'];
		}
		$text = Html::rawElement( 'div', $attrs, '' );

		return $text;
	}

}
And the code for function displayCalendarData in CargoExport.php is:
	/**
	 * Used for calendar format
	 */
	function displayCalendarData( $sqlQueries ) {
		$req = $this->getRequest();

		$colorArray = $req->getArray( 'color' );
		$textColorArray = $req->getArray( 'text_color' );
		$colorFieldArray = $req->getArray( 'color_field' );
		$textColorFieldArray = $req->getArray( 'text_color_field' );

		$datesLowerLimit = $req->getVal( 'start' );
		$datesUpperLimit = $req->getVal( 'end' );

		$displayedArray = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			foreach( $sqlQuery->mFieldStringAliases as $fieldName => $fieldAlias ) {
				if ( $fieldName == $colorFieldArray[0] ) {
					$colorFieldName = $fieldAlias ;
				}
				if ( $fieldName == $textColorFieldArray[0] ) {
					$textColorFieldName = $fieldAlias ;
				}
			}

			$dateFieldRealNames = array();
			$dateFieldAliases = array();
			foreach( $sqlQuery->mFieldDescriptions as $alias => $description ) {
				if ( $description->mType == 'Date' || $description->mType == 'Datetime' ) {
					$dateFieldAliases[] = $alias;
					$realFieldName = $sqlQuery->mAliasedFieldNames[$alias];
					$dateFieldRealNames[] = $realFieldName;
				}
			}
			$where = $sqlQuery->mWhereStr;
			if ( $where != '' ) {
				$where .= " AND ";
			}
			$where .= "(";
			foreach ( $dateFieldRealNames as $j => $dateField ) {
				if ( $j > 0 ) {
					$where .= " OR ";
				}
				$where .= "($dateField >= '$datesLowerLimit' AND $dateField <= '$datesUpperLimit')";
			}
			$where .= ")";
			$sqlQuery->mWhereStr = $where;

			$queryResults = $sqlQuery->run();
			foreach ( $queryResults as $queryResult ) {
				if ( array_key_exists( 'name', $queryResult ) ) {
					$eventTitle = $queryResult['name'];
				} else {
					$eventTitle = reset( $queryResult );
				}
				$title = Title::newFromText( $queryResult['_pageName'] );
				$startDateField = $dateFieldAliases[0];
				$startDate = $queryResult[$startDateField];
				$startDatePrecisionField = $startDateField . '__precision';
				$startDatePrecision = $queryResult[$startDatePrecisionField];
				if ( array_key_exists( $colorFieldName , $queryResult ) ) {
					$eventColor = $queryResult[$colorFieldName];
				} else {
					$eventColor = $colorArray[$i];
				}
				if ( array_key_exists( $textColorFieldName , $queryResult ) ) {
					$eventTextColor = $queryResult[$textColorFieldName];
				} else {
					$eventTextColor = $textColorArray[$i];
				}

				$curEvent = array(
					// Get first field for the title - not
					// necessarily the page name.
					'title' => $eventTitle,
					'url' => $title->getLocalURL(),
					'start' => $queryResult[$dateFieldAliases[0]],
					'end' => $queryResult[$dateFieldAliases[1]],
					'color' => $eventColor,
					'textColor' => $eventTextColor 
				);
				if ( $startDatePrecision != CargoStore::DATE_AND_TIME ) {
					$curEvent['allDay'] = true;
				}

				$displayedArray[] = $curEvent;
			}
		}
		print json_encode( $displayedArray );
	}
I suggest using with caution - all those colours can hurt one's eyes!
Duncan 18th November 2016
Wow, thank you! I'll look into this later, but everything here looks reasonable. And I'll try to test it tastefully. :) How should I credit you - as Duncan? Yaron Koren (talk) 19:24, 18 November 2016 (UTC)Reply
That's kind you want to Credit my very small contribution. Perhaps Duncan Crane?
Many thanks - Duncan 19, Nov 2016

Looking up a single feild

Hi, I'm sure I'm just missing something obvious, but I can't see how to insert the value from a single field lookup into wiki text.

The situation is this. I have a Boat table, with fields for Sail Number and Owner Name. I have another table for Race Result with fields for Race Position, Sail Number and Score. When I display a page corresponding to a Race Result, I want to display the Owner Name via a lookup on the Boat table using the Sail Number into the page.

What I wondered is do I use Cargo Query and, if so, how to insert the value into the page without any formatting (table, list etc)?

Many thanks

Duncan November 18, 2016

Would this work?
{{#cargo_query:tables=Boat,Race_Result |fields=Boat.Owner_Name |join=Boat.Sail_Number=Race_Result.Sail_Number |where=Race_Result._pageName={{PAGENAME}} }}
Yaron Koren (talk) 19:29, 18 November 2016 (UTC)Reply
Thanks Yaron, I'll give that a try. Duncan, 19th Nov 2016

Display map from address rather than coordinates?

I see that coordinates are mandatory for {{#cargo_display_map:...}} With Extension:Maps it is possible to insert any address into {{#display_map:...}} Is there any way to use Cargo to achieve the same end? Thanks Jonathan3 (talk) 23:08, 18 November 2016 (UTC)Reply

No - I deliberately didn't include geocoding, because I figured that it was always better for the user to get the coordinates when they were entering the location into the form. Assuming that this location is stored in a template, and edited with a form. Is that not the case here? Yaron Koren (talk) 23:19, 20 November 2016 (UTC)Reply
The potential users are unlikely to know how to obtain coordinates, and unlikely to do it even if the form explained how. I can use the Maps extension to show the address on the template page (for one location), but your maps display format (showing many locations) is very impressive and in an ideal world I'd like to be able to use it, or something similar, without requiring coordinates. Would there be any way to achieve this or similar? I've tried putting a Cargo query (list display format, semicolon delimiter) as a parameter to {{#display_map:...}} but it just shows a blank blue screen. Manually pasting the same Cargo output into {{#display_map...}} works fine so it may not be a Cargo problem. Thank you. Jonathan3 (talk) 23:41, 20 November 2016 (UTC)Reply
Just to be sure, do you know about the "googlemaps" input type in Page Forms? Yaron Koren (talk) 23:47, 20 November 2016 (UTC)Reply
To be honest I had been using an old Cargo version, and the "googlemaps" options didn't work because the Google key variable wasn't being used. I have tried it out now, and it works well. I have two questions though. (1) It would be good if the "Enter address here/Look up coordinates" box saved the address as well as the coordinates. Is this possible? Otherwise the user has to enter the address twice (in my case anyway - for an "Address" field and the "Coordinates" field. (2) On the "googlemaps" input type, if I click a new location it updates the coordinates, but if I move an existing red pointer it doesn't update the coordinates. Is this something that can be changed? I would like both actions to update the coordinates. I'm using MW 1.27.1, Cargo 1.2, and Page Forms 4.0.2. Thank you very much again. Jonathan3 (talk) 22:59, 21 November 2016 (UTC)Reply
No on the first one, unfortunately - people have been asking about that for a long time, but there's no easy way to do it. The second one sounds like a bug that may be fixable. Yaron Koren (talk) 03:18, 22 November 2016 (UTC)Reply
In relation to the first point, I was able to make the "Enter address here/Look up coordinates" auto-update each time the (separate) "Address" text input box was updated. This achieves a similar end by a different means. It only does anything when there is a text input box called "Address", so I guess if you were to go with it there would be internationalisation considerations. Anyway, here's what I came up with, for PF_TextInput.php, in public static function getHTML, just before "$text = ...":
		if (preg_match("#\[Address\]#", $input_name)) {
			$inputAttrs['onchange'] = "document.getElementsByClassName('pfAddressInput')[0].value=this.value";
		}
This perhaps really belongs on the Extension:Page Forms talk page but it seemed better to continue the conversation here. Jonathan3 (talk) 23:13, 22 November 2016 (UTC)Reply
In relation to the second point, it seems that you have a listener for clicking (and creating/moving a marker) but not for dragging. The quickest solution is to amend function googleMapsSetMarker so that draggable is set to false (which requires a click to move the marker) but I'll look into it further as soon as I get a chance. Jonathan3 (talk) 23:45, 22 November 2016 (UTC)Reply
See a proposed solution in Extension talk:Page Forms#Dragging marker in Google Maps does not change the coordinates. Jonathan3 (talk) 00:44, 3 December 2016 (UTC)Reply
Thanks for moving the discussion over. Yaron Koren (talk) 23:21, 4 December 2016 (UTC)Reply

Error with some formats (json, csv) but not with default format: Table "..." is not included within the join conditions

  • MW 1.27.1
  • PHP 5.6.11
  • MySQL 5.6.28
  • Cargo 1.2

The same query raises an error when the json or csv formats are used but it works fine if no format is specified:

{{#cargo_query:
tables=RecursosDBN, CentrosDB
|join on=RecursosDBN.centros HOLDS CentrosDB._pageTitle
|fields=RecursosDBN._pageName, denom
|format = csv
}}
[49a018906b39af2ff8820a3a] /w/index.php?title=Especial:CargoExport&tables=RecursosDBN%2CRecursosDBN__centros%2CCentrosDB&join+on=RecursosDBN.centros+HOLDS+CentrosDB._pageTitle&fields=RecursosDBN._pageName%2C+denom&&order+by=%60cargo__RecursosDBN%60.%60_pageName%60&limit=100&format=csv MWException from line 320 of /var/www/html/w/extensions/Cargo/CargoSQLQuery.php: Error: Table "RecursosDBN__centros" is not included within the join conditions.

Backtrace:

#0 /var/www/html/w/extensions/Cargo/CargoSQLQuery.php(58): CargoSQLQuery->setCargoJoinConds(string)
#1 /var/www/html/w/extensions/Cargo/specials/CargoExport.php(46): CargoSQLQuery::newFromValues(string, string, NULL, string, NULL, NULL, string, string)
#2 /var/www/html/w/includes/specialpage/SpecialPage.php(479): CargoExport->execute(NULL)
#3 /var/www/html/w/includes/specialpage/SpecialPageFactory.php(576): SpecialPage->run(NULL)
#4 /var/www/html/w/includes/MediaWiki.php(282): SpecialPageFactory::executePath(Title, RequestContext)
#5 /var/www/html/w/includes/MediaWiki.php(745): MediaWiki->performRequest()
#6 /var/www/html/w/includes/MediaWiki.php(519): MediaWiki->main()
#7 /var/www/html/w/index.php(43): MediaWiki->run()
#8 {main}


For example, the query at http://discoursedb.org/wiki/Item_query raises an error if the format is changed to csv

{{#cargo_query:tables=Items,Authors
|join on=Items.Author HOLDS Authors._pageName
|fields=Items._pageName=Item,Items.Author,Political_affiliation,Source,DATE_FORMAT(Date, "%M %e, %Y")=Publication date,CONCAT('[', URL, ' View item]')=Link
|order by=Date
|format=csv
}}
Sorry about that! I think I just fixed it. Yaron Koren (talk) 04:31, 22 November 2016 (UTC)Reply
Thanks, Yaron. Yes. I think it's fixed now. --Lmorillas (talk) 19:53, 22 November 2016 (UTC)Reply

Problem using Where in Cargo Query with Calendar format

Hi

I have a query as follows which correctly displays in the calendar format (sorry its a bit complex):

{{#cargo_query:
tables=Events,Codes,Page_properties
|join on=Events.Event_Type=Codes._pageName,Events._pageName=Page_properties._pageName
|fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_End_Date_Time,Events.Event_Type,Events.Calendar_Groups,Codes.Colour,Codes.Text_Colour
|format=calendar
|color field=Codes.Colour
|text color field=Codes.Text_Colour
}}

The Event table includes a list field Events.Calendar_Groups. When I introduce a 'where' clause including a 'HOLDS' operator to test for a value in the list field the calendar is empty. If I remove the calendar format parameters and display, the resulting table is correct.

{{#cargo_query:
tables=Events,Codes,Page_properties
|join on=Events.Event_Type=Codes._pageName,Events._pageName=Page_properties._pageName
|fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_End_Date_Time,Events.Event_Type,Events.Calendar_Groups,Codes.Colour,Codes.Text_Colour
|where=Events.Calendar_Groups HOLDS "Admin:GP0000003" 
|format=calendar
|color field=Codes.Colour
|text color field=Codes.Text_Colour
}}

I wondered if there was reason why the Where/Holds operator might be disallowed in queries with the calendar format?

Many thanks

Duncan 22nd Nov 2016

You may be seeing the same issue as the section directly above this one. Could you try upgrading to the very latest Cargo code, and see if the problem is still there? Yaron Koren (talk) 15:59, 22 November 2016 (UTC)Reply
Thanks Yaron.
I gave this a try but it still didn't seem to work. However, I did apply the Calendar changes I'd done over the weekend to version 1.2 so maybe this overwrote some of your changes. Do you think this is possible? I don't have much time to investigate for now but if you have any thoughts it might help speed things when I do.
Kind regards Duncan, 22 Nov 2016
I'd recommend looking at the HTML source of the non-working calendar page, finding the URL that includes "Special:CargoExport", replacing the "&amp;"s there with just "&", and then going to that URL, and seeing if there are any error messages. Yaron Koren (talk) 20:06, 22 November 2016 (UTC)Reply
Thanks Yaron - that was certainly helpful. I have now tried a few options looking at the HTML request produced for CargoExport. The problem seem to arise when the helper table for a List Field is added to the sql request. For example the following request produces a pair of brackets "[]" which I take to mean that CargoExport did something with it:
https://cmswiki.farm/x/mw-1.26/index.php?title=Special:CargoExport&tables=Events%2CCodes%2CPage_properties&join+on=Events.Event_Type%3DCodes._pageName%2CEvents._pageName%3DPage_properties._pageName&fields=Events._pageName%2CEvents.Event_Start_Date_Time%2CEvents.Event_End_Date_Time%2CEvents.Event_Type%2CEvents.Calendar_Groups%2CCodes.Colour%2CCodes.Text_Colour%2CPage_properties.Title%3Dname&&order+by=%60cargo__Events%60.%60_pageName%60&limit=100&format=fullcalendar

However the following request produces an HTTP 500 Internal Server Error:

https://cmswiki.farm/x/mw-1.26/index.php?title=Special:CargoExport&tables=Events%2CEvents__Calendar_Groups%2CCodes%2CPage_properties&join+on=Events.Event_Type%3DCodes._pageName%2CEvents._pageName%3DPage_properties._pageName&fields=Events._pageName%2CEvents.Event_Start_Date_Time%2CEvents.Event_End_Date_Time%2CEvents.Event_Type%2CEvents.Calendar_Groups%2CCodes.Colour%2CCodes.Text_Colour%2CPage_properties.Title%3Dname&&order+by=%60cargo__Events%60.%60_pageName%60&limit=100&format=fullcalendar
The difference between them being the following table being added to the join:
Events__Calendar_Groups
Unfortunately I can't look into this more until tomorrow but if you've any more suggestions I'd be grateful?
Many thanks, Duncan, 24th Nov 2016
Hi again
I think I now understand the problem but I haven't been able to find a proper fix although I do have a hack that seems to work.
The problem is with the data url that is created for the calendar html to send to CargoExport to populate the calendar with data. If one is using a cargo list field in a Where clause then the data url includes the data table for the list field in its Tables parameter and references this in the Where clause. For example if an Events table contains a list field Calendar_Groups the data url is as follows (I put in some line feeds to make it clearer):
https://cmswiki.farm/x/mw-1.26/index.php?title=Special:CargoExport
&tables=Events%2CEvents__Calendar_Groups%2CCodes%2CPage_properties
&join+on=Events.Event_Type%3DCodes._pageName%2CEvents._pageName%3DPage_properties._pageName
&fields=Events._pageName%2CEvents.Event_Start_Date_Time%2CEvents.Event_End_Date_Time%2CEvents.Event_Type
%2CEvents.Calendar_Groups%2CCodes.Colour%2CCodes.Text_Colour%2CPage_properties.Title%3Dname
&where=`cargo__Events__Calendar_Groups`.`_value`%3D%27Admin%3AGP0000003%27
&order+by=`cargo__Events`.`_pageName`
&limit=100
&format=fullcalendar
&&color+field[0]=Codes.Colour
&text+color+field[0]=Codes.Text_Colour
&text+color[0]=
&start=2016-10-30
&end=2016-12-11
&_=1480097788550
However CargoExport seems to want the data url as it is in the Cargo Query without expanding the list field in the Table and Where clauses as follows:
https://cmswiki.farm/x/mw-1.26/index.php?title=Special:CargoExport
&tables=Events%2CCodes%2CPage_properties
&join+on=Events.Event_Type%3DCodes._pageName%2CEvents._pageName%3DPage_properties._pageName
&fields=Events._pageName%2CEvents.Event_Start_Date_Time%2CEvents.Event_End_Date_Time%2CEvents.Event_Type
%2CEvents.Calendar_Groups%2CCodes.Colour%2CCodes.Text_Colour%2CPage_properties.Title%3Dname
&where=Events.Calendar_Groups+HOLDS+%27Admin%3AGP0000003%27
&order+by=`cargo__Events`.`_pageName`
&limit=100
&format=fullcalendar
&&color+field[0]=Codes.Colour
&text+color+field[0]=Codes.Text_Colour
&text+color[0]=
&start=2016-10-30
&end=2016-12-11
&_=1480098232918
The Cargo Query that is used to generate these data urls is as follows:
{{#cargo_query:
tables=Events,Codes,Page_properties
|join on=Events.Event_Type=Codes._pageName,Events._pageName=Page_properties._pageName
|fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_End_Date_Time,
Events.Event_Type,Events.Calendar_Groups,Codes.Colour,Codes.Text_Colour,Page_properties.Title=name
|where=Events.Calendar_Groups HOLDS 'Admin:GP0000003' 
|format=calendar
|color field=Codes.Colour
|text color field=Codes.Text_Colour
}}
It appears that this creation of the parameters used by the data url is happening in the newFromValues function in CargoSQLQuery when it calls the handleVirtualFields function. However it seems to do this more than once and the modified parameters appear after the first call but I haven't been able to work out why.
I have created a hack which is very ugly. In the sqlQueriesToQueryParams function of CargoDeferredFormat, I test
$sqlQuery->mWhereStr 
to see if it is different to
$sqlQuery->mOrigWhereStr
If it is I set
$queryParams['where']
to
$sqlQuery->mOrigWhereStr
and
$queryParams['tables']
to
$sqlQuery->mTablesStr
as these two variables contain what was in the original CargoQuery in my wiki page. If I do this then the Calendar format appears to work correctly.
I am very nervous of this hack as I don't know if it will upset anything else, so if you've any thoughts where I might put a proper fix that would be fantastic.
Many thanks, Duncan, 25th November 2016
See my response in the duplicate entry below. Yaron Koren (talk) 20:34, 27 November 2016 (UTC)Reply

How to use a constant (not a field value) in the field list of a query?

Older cargo versions supported queries like:

{{#cargo_query:tables=Items
|fields=Items._pageName=Item, "Item"=Type
}}

But now it raises an error

Query: SELECT `cargo__Items`.`_pageName` AS `Item`,`"Item"` AS `Type` FROM `cargo__Items` ORDER BY `cargo__Items`.`_pageName` LIMIT 100 Function: CargoSQLQuery::run Error: 1054 Unknown column '"Item"' in 'field list' (127.0.0.1)

--Lmorillas (talk) 10:49, 23 November 2016 (UTC)Reply

Yes, this used to work... I don't know when it stopped working, though there have been a lot of changes to query parsing. I just fixed it to work again, although now you have to use single quotes - 'Item' instead of "Item". (Which is more correct, SQL-wise.) Yaron Koren (talk) 20:36, 27 November 2016 (UTC)Reply

CargoUtils.php on line 47

Hello Yaron,

I'm trying to update my mediawiki/cargo site from (cargo 0.10) to (cargo 1.2) on mediawiki (1.24.1). In my query pages or executing the cargoRecreateData.php I've got the following error message :

Parse error: syntax error, unexpected '[' in /var/www/html/wiki/extensions/Cargo-1.2/CargoUtils.php on line 47

Any Idea ? Thanks for answer --Guillaume Prêcheur (talk) 09:18, 25 November 2016 (UTC)Reply

Ah - at some point a few months ago, that line was changed to use the relatively new syntax for arrays, "[]", which doesn't work for PHP versions before 5.4. I think that was a mistake; I just changed the syntax back, so the latest code should work for you. Yaron Koren (talk) 16:10, 25 November 2016 (UTC)Reply
Thanks, I checkout the release 11/27/2016 - seems to work ! Thanks --Guillaume Prêcheur (talk) 08:58, 28 November 2016 (UTC)Reply

Using the result of a #cargo_query in an #expr

I'm trying to do different things depending on how many results there are to a query: if there are just a few, display them all; if there are many, show only the results of a more restrictive query, and provide a link to a drilldown that shows the larger result set. I've run into a problem feeding the result from a #cargo_query into an expression. (I have the ParserFunctions and Variables extensions installed). Here's an example:

{{#vardefine:num_results | {{#cargo_query:
tables=Documents
|fields=COUNT(_pageName)
|where=Markets HOLDS "{{PAGENAME}}"
|default=0}} }}

There are {{#var:num_results}} results. 
{{#ifexpr: {{#var:num_results}} > 50 | This is more than 50. | This is 50 or fewer. }}

This produces the following output:

 There are 100 results. Expression error: Unrecognized punctuation character "?".

(The question mark there seems to be some special character. It's not actually visible in the error message, but it shows up when pasted here. It shows as an upside-down question mark in a text editor. I don't know where it's coming from. The correct 100 value shown at the beginning of the output seems to consist of just those three characters -- nothing weird in there.)

If I replace the #cargo_query call with a simple number, the #ifexpr call works as expected, so it seems to be an issue with the #cargo_query result. I have tried specifying format=list, which I imagine gives the simplest output, but it makes no difference. I have also tried putting the #cargo_query call directly inside an #expr call (avoiding the use of Variables and #ifexpr), but this also still results in the same error.

I have also tried passing the output of #cargo_query to #number_format (from the NumberFormat extension). This gives the error:

 First argument to "number_format" must be a number.

So the issue seems to be that what #cargo_query returns looks like a number, but is not treated as such by other functions. I'd be grateful for any hints you can give for how to avoid this error. This is with Cargo 1.2 and ParserFunctions 1.6.0 on MediaWiki 1.27.0 on PHP 5.6.24. Many thanks. Paul T (talk) 18:05, 25 November 2016 (UTC)Reply

Adding the "no html" parameter to the #cargo_query call might help. Yaron Koren (talk) 19:47, 25 November 2016 (UTC)Reply
Thank you! That works. Apologies for overlooking that option. Paul T (talk) 19:58, 25 November 2016 (UTC)Reply
Great! Yaron Koren (talk) 02:57, 26 November 2016 (UTC)Reply

Cargo Calendar Format - two features and a problem possibly solved

Hi Yaron

I've been playing with the cargo calendar format some more and have added a couple of features which I wondered if you might incorporate?

The first enables one to set the aspect ratio of the calendar so effectively setting its height relative to its width. This uses fullCalendar's aspect ratio parameter. The second allows one to identify a field to be displayed in a pop up box when the mouse is over an event. This is done by aliasing the field with "=description" in a similar way that '=name' is used to identify an alternative field to use as an event's title in the calendar.

This is achieved by changes to ext.cargo.alendar.js as follows:

/* global moment */

$(document).ready(function() {

	// page is now ready, initialize the calendar...
	$('.cargoCalendar').each( function() {
		var dataURL = decodeURI( $(this).attr('dataurl') );
		var startView = $(this).attr('startview');
		var startDate = moment( $(this).attr('startdate') );
		var aspectRatio = $(this).attr('aspectratio');
		$(this).fullCalendar({
			// put your options and callbacks here
			events: dataURL,
			header: {
				left: 'today prev,next',
				center: 'title',
				right: 'month,basicWeek,basicDay'
			},
			aspectRatio: aspectRatio,
			defaultView: startView,
			defaultDate: startDate,
			// add event name to title attribute on mouseover
			eventMouseover: function(event, jsEvent, view) {
				if (view.name !== 'agendaDay') {
					$(jsEvent.target).attr('title', event.description);
				}
			},
		});
	});

});

Changes to the displayCalendarData function in CargoExport as follows:

	/**
	 * Used for calendar format
	 */
	function displayCalendarData( $sqlQueries ) {
		$req = $this->getRequest();
		$colorArray = $req->getArray( 'color' );
		$textColorArray = $req->getArray( 'text_color' );
		$colorFieldArray = $req->getArray( 'color_field' );
		$textColorFieldArray = $req->getArray( 'text_color_field' );

		$datesLowerLimit = $req->getVal( 'start' );
		$datesUpperLimit = $req->getVal( 'end' );

		$displayedArray = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			foreach( $sqlQuery->mFieldStringAliases as $fieldName => $fieldAlias ) {
				if ( $fieldName == $colorFieldArray[0] ) {
					$colorFieldName = $fieldAlias ;
				}
				if ( $fieldName == $textColorFieldArray[0] ) {
					$textColorFieldName = $fieldAlias ;
				}
			}

			$dateFieldRealNames = array();
			$dateFieldAliases = array();
			foreach( $sqlQuery->mFieldDescriptions as $alias => $description ) {
				if ( $description->mType == 'Date' || $description->mType == 'Datetime' ) {
					$dateFieldAliases[] = $alias;
					$realFieldName = $sqlQuery->mAliasedFieldNames[$alias];
					$dateFieldRealNames[] = $realFieldName;
				}
			}
			$where = $sqlQuery->mWhereStr;
			if ( $where != '' ) {
				$where .= " AND ";
			}
			$where .= "(";
			foreach ( $dateFieldRealNames as $j => $dateField ) {
				if ( $j > 0 ) {
					$where .= " OR ";
				}
				$where .= "($dateField >= '$datesLowerLimit' AND $dateField <= '$datesUpperLimit')";
			}
			$where .= ")";
			$sqlQuery->mWhereStr = $where;

			$queryResults = $sqlQuery->run();
			foreach ( $queryResults as $queryResult ) {
				if ( array_key_exists( 'name', $queryResult ) ) {
					$eventTitle = $queryResult['name'];
				} else {
					$eventTitle = reset( $queryResult );
				}
				if ( array_key_exists( 'description', $queryResult ) ) {
					$eventDescription = $queryResult['description'];
				} else {
					$eventDescription = null;
				}
				$title = Title::newFromText( $queryResult['_pageName'] );
				$startDateField = $dateFieldAliases[0];
				$startDate = $queryResult[$startDateField];
				$startDatePrecisionField = $startDateField . '__precision';
				$startDatePrecision = $queryResult[$startDatePrecisionField];
				if ( array_key_exists( $colorFieldName , $queryResult ) ) {
					$eventColor = $queryResult[$colorFieldName];
				} else {
					$eventColor = $colorArray[$i];
				}
				if ( array_key_exists( $textColorFieldName , $queryResult ) ) {
					$eventTextColor = $queryResult[$textColorFieldName];
				} else {
					$eventTextColor = $textColorArray[$i];
				}

				$curEvent = array(
					// Get first field for the title - not
					// necessarily the page name.
					'title' => $eventTitle,
					'url' => $title->getLocalURL(),
					'start' => $queryResult[$dateFieldAliases[0]],
					'end' => $queryResult[$dateFieldAliases[1]],
					'color' => $eventColor,
					'textColor' => $eventTextColor,
					'description' => $eventDescription 
				);
				if ( $startDatePrecision != CargoStore::DATE_AND_TIME ) {
					$curEvent['allDay'] = true;
				}
				$displayedArray[] = $curEvent;
			}
		}
		print json_encode( $displayedArray );
	}

And changes to the queryAndDisplay function of CargoCalendarFormats as follows:

	/**
	 *
	 * @param array $sqlQueries
	 * @param array $displayParams
	 * @param array $querySpecificParams
	 * @return string
	 */
	function queryAndDisplay( $sqlQueries, $displayParams, $querySpecificParams = null ) {
		$this->mOutput->addModules( 'ext.cargo.calendar' );
		$ce = SpecialPage::getTitleFor( 'CargoExport' );
		$queryParams = $this->sqlQueriesToQueryParams( $sqlQueries );
		$queryParams['format'] = 'fullcalendar';
		$queryParams['color'] = array();
		foreach ( $sqlQueries as $i => $sqlQuery ) {
			if ( $querySpecificParams != null ) {
				if ( array_key_exists( 'color', $querySpecificParams[$i] ) ) {
					$queryParams['color'][] = $querySpecificParams[$i]['color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'color field', $displayParams ) ) {
					$queryParams['color field'][] = $displayParams['color field'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['color field'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'text color field', $displayParams ) ) {
					$queryParams['text color field'][] = $displayParams['text color field'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['text color field'][] = '';
				}
			}
			if ( $displayParams != null ) {
				if ( array_key_exists( 'text color', $displayParams ) ) {
					$queryParams['text color'][] = $displayParams['text color'];
				} else {
					// Stick an empty value in there, to
					// preserve the order for the queries
					// that do contain a color.
					$queryParams['text color'][] = '';
				}
			}
		}
		if ( array_key_exists( 'width', $displayParams ) ) {
			$width = $displayParams['width'];
			// Add on "px", if no unit is defined.
			if ( is_numeric( $width ) ) {
				$width .= "px";
			}
		} else {
			$width = "100%";
		}
		if ( array_key_exists( 'aspect ratio', $displayParams ) ) {
			$aspectRatio = $displayParams['aspect ratio'];
			// check tha aspect ratio is numeric and set default if not.
			if ( !is_numeric( $aspectRatio ) ) {
				$aspectRatio = 1.35;
			}
		} else {
			$aspectRatio = 1.35;
		}

		$attrs = array(
			'class' => 'cargoCalendar',
			'dataurl' => $ce->getFullURL( $queryParams ),
			'style' => "width: $width",
			'aspectratio' => $aspectRatio
		);

		if ( array_key_exists( 'view', $displayParams ) ) {
			$view = $displayParams['view'];
			// Enable simpler view names.
			if ( $view == 'day' ) {
				$view = 'basicDay';
			} elseif ( $view == 'week' ) {
				$view = 'basicWeek';
			}
			$attrs['startview'] = $view;
		} else {
			$attrs['startview'] = 'month';
		}
		if ( array_key_exists( 'start date', $displayParams ) ) {
			$attrs['startdate'] = $displayParams['start date'];
		}
		$text = Html::rawElement( 'div', $attrs, '' );

		return $text;
	}

}

An example Cargo Query using these new features is:

{{#cargo_query:
tables=Events,Codes,Page_properties
|join on=Events.Event_Type=Codes._pageName,Events._pageName=Page_properties._pageName
|fields=Events._pageName,Events.Event_Start_Date_Time,Events.Event_End_Date_Time,Events.Event_Type,Events.Calendar_Groups,Codes.Colour,Codes.Text_Colour,Page_properties.Title=name,Page_properties.Description=description
|where=Events.Calendar_Groups HOLDS 'Admin:GP0000003' 
|format=calendar
|color field=Codes.Colour
|text color field=Codes.Text_Colour
|aspect ratio=2
}}

Finally in an earlier topic [here] I though I'd hit a problem with the calendar format when it tries to display a Cargo Query which includes a 'where ... HOLDS..." condition. You may have missed the update as there have been a number of new topics since that one was started. I managed to get an error print out of this as follows:

A database query error has occurred. This may indicate a bug in the software.

Query:
SELECT `cargo__Events`.`_pageName` AS `_pageName`,`cargo__Events`.`Event_Start_Date_Time` AS `Event Start Date Time`,`cargo__Events`.`Event_End_Date_Time` AS `Event End Date Time`,`cargo__Events`.`Event_Type` AS `Event Type`,`Calendar_Groups__full` AS `Calendar Groups`,`cargo__Codes`.`Colour` AS `Colour`,`cargo__Codes`.`Text_Colour` AS `Text Colour`,`cargo__Page_properties`.`Title` AS `name`,`cargo__Events`.`Event_Start_Date_Time__precision` AS `Event Start Date Time__precision`,`cargo__Events`.`Event_End_Date_Time__precision` AS `Event End Date Time__precision` FROM `cargo__Events` LEFT OUTER JOIN `cargo__Codes` ON ((`cargo__Events`.Event_Type=`cargo__Codes`._pageName)) LEFT OUTER JOIN `cargo__Page_properties` ON ((`cargo__Events`._pageName=`cargo__Page_properties`._pageName)) WHERE `cargo__Events__Calendar_Groups`.`_value`='Admin:GP0000003' AND ((`cargo__Events`.`Event_Start_Date_Time` >= '2016-10-30' AND `cargo__Events`.`Event_Start_Date_Time` <= '2016-12-11') OR (`cargo__Events`.`Event_End_Date_Time` >= '2016-10-30' AND `cargo__Events`.`Event_End_Date_Time` <= '2016-12-11')) ORDER BY `cargo__Events`.`_pageName` LIMIT 100
Function: CargoSQLQuery::run
Error: 1054 Unknown column 'cargo__Events__Calendar_Groups._value' in 'where clause' (localhost)

I'd updated the previous topic with what I thought might be a fix. In the sqlQueriesToQueryParams function of CargoDeferredFormat, I test

$sqlQuery->mWhereStr 

to see if it is different to

$sqlQuery->mOrigWhereStr

If it is I set

$queryParams['where']

to

$sqlQuery->mOrigWhereStr

as this variable contains what was in the original CargoQuery in my wiki page. If I do this then the Calendar format appears to work correctly.

I am nervous of this hack as I don't know if it will upset anything else, so I wondered what you thought?.

Many thanks, Duncan 26th November 2016

Thanks for that suggested fix. You didn't need to paste in all the code again, by the way. I came up with a fix that's similar to yours, which I just checked in, so hopefully everything works now. The "description" idea is very clever; I'll add that in. For "aspect ratio" - what's the point of that parameter? When would it be useful to change the ratio from the default? Yaron Koren (talk) 20:40, 27 November 2016 (UTC)Reply
Hi Yaron thanks for this. Sorry to clutter up this page. The new versions of the code included the additional features described in this post. I should have just emailed them to you rather than reinserting them so apologies there. For some reason, the default Calendar format always seems to run off the bottom of the page. Some of my users suggested it would be a lot nicer if they didn't have to scroll up and down to see all the entries so the aspect ratio feature of full calendar seemed as straightforward way to achieve this (they are a bit elderly so also a bit demanding as their fine motor skills aren't that great!). Of course, if a user doesn't want to, they don't have to specify the aspect ratio and they would still get the default. Anyway I hope you will consider it as it would be nice not to patch the code each time there is a release. Thank you again for all your fantastic efforts, your code has transformed our use of wikis.
Many thanks
Duncan 28 November 2016
No problem about the code, sorry - I think I thought the bug fix part was quite a bit longer than it really was. Though emailing me patches is also fine. For the aspect ratio - I should have been clearer. I can understand wanting to control the height; but doing it via aspect ratio seems strange, because it might lead to an unnecessarily short display on smartphones, an unnecessarily tall display on large monitors, etc. The FullCalendar JS library also offers a "height" parameter - might that be better? Yaron Koren (talk) 16:53, 28 November 2016 (UTC)Reply
Ah - now I understand. I'll have a look at the height option. I think it should be straightforward so hopefully will get around to it sometime this week. Thanks you for considering the other features too.
Kind regards, Duncan 28th November 2016.

Cargo with Foundation skin tabs

I would like to use #cargo_display_map to show a location in both Googlemaps and Openlayers, with each one in a Foreground skin tab. The Foreground skin tabs are described here. A problem arises when Googlemaps is not the one to appear on the first tab. A grey rectangle (with the Google logo) appears instead of a map. The same problem occurs when I use a div of class "mw-collapsible mw-collapsed". So I think there may be a problem about how the map is initialised.

This works fine (both maps are shown) so it's just merely having Googlemaps second that creates the problem:

{{#cargo_display_map:point=51.517450, -0.127697|service=openlayers}}
{{#cargo_display_map:point=51.517450, -0.127697|service=googlemaps}}

This doesn't work with Googlemaps but does work with Openlayers:

<div class="mw-collapsible mw-collapsed">
Googlemaps
<div class="mw-collapsible-content">
{{#cargo_display_map:point=51.517450, -0.127697|service=googlemaps}}
</div>
</div>

This Foreground skin tab structure does not work when Googlemaps is in the second tab (NB it works the other way round when Openlayers is second):

<div class="section-container auto" data-section>
  <div class="section">
    <p class="title" data-section-title>Openlayers Map</p>
    <div class="content" data-section-content>
{{#cargo_display_map:point=51.517450, -0.127697|service=openlayers}}
   </div>
  </div>

  <div class="section">
    <p class="title" data-section-title>Google Map</p>
    <div class="content" data-section-content>
{{#cargo_display_map:point=51.517450, -0.127697|service=googlemaps}}
   </div>
  </div>
</div>

Thanks in advance for any assistance you can offer. Jonathan3 (talk) 22:13, 27 November 2016 (UTC)Reply

Can I add that now, even with Googlemaps in tab 1 and Openlayers in tab 2, the Googlemaps doesn't work - until I refresh the page on my browser? Jonathan3 (talk) 00:27, 28 November 2016 (UTC)Reply

That's pretty bad. This looks the issue - there's a suggested fix there, but I don't know if it can be used here. A line of JavaScript needs to be called, that will redraw/"resize" the map - but I don't know how to get that call to be triggered if a div is expanded, or a tab is selected... maybe there's some way involving JS hooks, or something? Yaron Koren (talk) 21:55, 29 November 2016 (UTC)Reply
I had a similar problem previously, when trying to put a dynamic table, timeline, and calendar into three tabs. I can't remember which wouldn't initialise properly unless in tab 1 - I think is was timeline and/or calendar. In the end I used separate pages, which works better from a page-loading time point of view anyway. Jonathan3 (talk) 21:40, 2 December 2016 (UTC)Reply

Removing namespace when displaying page names

I have a form which automatically adds new pages to a namespace (using query string=namespace=<namespace>). When I display them in a Cargo query, each page is shown as Namespace:Pagetitle. I'd prefer it just to display the page title (without the namespace). How could I do this? Thanks. Jonathan3 (talk) 22:31, 27 November 2016 (UTC)Reply

You can include _pageTitle instead of _pageName in the list of query fields. Yaron Koren (talk) 22:51, 27 November 2016 (UTC)Reply
Thanks for the quick reply. That works but also removes the internal link to the relevant wiki page. Is there a way of keeping it as a link (like _PageName) but without the namespace (like _PageTitle)? Jonathan3 (talk) 00:47, 28 November 2016 (UTC)Reply
PS I've just tried this, which seems to work...
|fields= CONCAT("[[<namespace>:",_pageTitle,"|",_pageTitle,"]]")=Name
... with <namespace> replaced by the name of the relevant namespace. But I'm sure there is something better than this! Thanks. Jonathan3 (talk) 00:56, 28 November 2016 (UTC)Reply
PS again - that works with dynamic tables but not googlemaps (where it misses out the Name field altogether). Jonathan3 (talk) 00:59, 28 November 2016 (UTC)Reply
The only slightly better option I can think of is CONCAT("[[",_pageName,"|",_pageTitle,"]]"). I'll have to look into that googlemaps thing. Yaron Koren (talk) 15:44, 28 November 2016 (UTC)Reply

Googlemaps in responsive skin

Using the Foreground skin, to make the map the same width as the normal width of the website (and therefore to avoid the problem of having a map too wide) you can set the "width" to "inherit". The default setting is based in pixels and messes up the display (e.g. it's too wide on my iPhone). I didn't want to edit the extension page myself. Jonathan3 (talk) 00:16, 29 November 2016 (UTC)Reply

Clustering option for maps

Are there any plans to add this to the Cargo maps output formats? It's available in the Extension:Maps extension (details and examples here). Thanks. Jonathan3 (talk) 23:24, 29 November 2016 (UTC)Reply

I thought about adding this in - it wouldn't be hard to do - but I wasn't sure how useful clustering would be as a feature; I rarely see it in use. What do you think? Yaron Koren (talk) 02:48, 30 November 2016 (UTC)Reply
I've rarely seen it either, but (or maybe "so") when I see it I am impressed by it. If you could add it, I think it would be great. Out of interest, is there a comparison anywhere comparing the Maps extension with the Cargo maps output types? Jonathan3 (talk) 01:20, 1 December 2016 (UTC)Reply
Alright. No. Yaron Koren (talk) 03:38, 1 December 2016 (UTC)Reply

Link error with Timeline format

Hi Yaron, I noticed a problem in the event popup window of the timeline component viewer: the link to access to the wiki page has a bad base url adress and doesn't target the event page ! Any Idea ? --Guillaume Prêcheur (talk) 10:29, 30 November 2016 (UTC)Reply

This works fine for me. Is there anything unusual in your query, or in the wiki's URL structure? Yaron Koren (talk) 13:53, 30 November 2016 (UTC)Reply
This won't necessarily help Guillaume, but may reassure others - it works fine for me with MW1.27.1 and Cargo 1.2, with short URLs and no "wiki/" directory in the URL. Jonathan3 (talk) 21:36, 2 December 2016 (UTC)Reply

£ instead of £ [solved]

This appears in Cargo results, but not in normal page transclusion or DPL2/3 results from the same sources. Do you know why this might be? Thanks. Jonathan3 (talk) 01:24, 1 December 2016 (UTC)Reply

I can't reproduce this problem. What's the type of the field? And what kind of database are you using? Yaron Koren (talk) 03:37, 1 December 2016 (UTC)Reply
Strangely when I edited the page and saved it without making any changes, Cargo displayed the £ sign correctly. The same happened with another page where the † (dagger) had been shown as â€. These were in two different tables, but both were in a field of type Wikitext (size=2000). The Mediawiki MySQL tables are a mixture of utf8_general_ci and latin1_swedish_ci. The Cargo MySQL tables (in a different database) are all latin1_swedish_ci. I hadn't noticed this problem before upgrading MW and Cargo recently, though can't say for sure that it wasn't there. Jonathan3 (talk) 21:17, 1 December 2016 (UTC)Reply
Alright - let me know if it happens again. Yaron Koren (talk) 03:16, 2 December 2016 (UTC)Reply
I think I've sort of got to the bottom of this. I checked the MySQL table before and after a null edit of a template page, and the relevant field was updated (from the £ or †or similar set of characters) to the original character (a smart quotation mark from Word, a dagger symbol, etc). I guess that between Cargo version 0.9 (when the pages were created) and version 1.2 (which I'm on now), there was some change in the way that Cargo stored these characters. Going to the template page and recreating the data fixed the problem for every page. Should I change something about my database to make everything utf8_general_ci, or should I just leave it now? Jonathan3 (talk) 21:06, 2 December 2016 (UTC)Reply
Oh, that's interesting - I didn't know that, though then again a lot of things have changed in the code. I'd say, if it works, no need to change anything... Yaron Koren (talk) 21:56, 2 December 2016 (UTC)Reply

"Order by" does not work with Dynamic Table [solved]

A Cargo query with the following lines...

|format=dynamic table
|order by=Date ASC

...shows the results ordered by _pageName, whereas a query with the following lines...

|format=table
|order by=Date ASC

...sorts the results by Date, as expected. Is there something I should do to allow sorting when using the dynamic table output type? Thanks in advance. Jonathan3 (talk) 21:30, 2 December 2016 (UTC)Reply

Yes, someone else noted that some problem, above. I need to fix it. Yaron Koren (talk) 21:57, 2 December 2016 (UTC)Reply
This has now been fixed. Yaron Koren (talk) 04:12, 5 December 2016 (UTC)Reply

Special:Drilldown always fails with query error [solved]

With MW 1.27.1 and Cargo 1.2, I could not get Special:Drilldown to work. This is because $wgDBprefix is not being prepended to any field name in CargoSpecialDrilldown.php. The problem is solved (for me at least) by adding $wgDBprefix . each time 'cargo__' appears in that file, and global $wgDBprefix; at the beginning of the relevant functions. If anyone has an idiot's guide to the proper way of submitting proposed patches for MediaWiki extensions then I would welcome it. Jonathan3 (talk) 23:27, 4 December 2016 (UTC)Reply

Sorry about that - I meant a while ago to fix the hardcoding of "cargo__" in CargoSpecialDrilldown.php, but I forgot. I just checked in a fix. As for submitting patches - if you have a diff of your changes, there are various ways to do it - put it here, email it to me, create a bug report in Phabricator and attach the patch, pastebin it... Yaron Koren (talk) 01:43, 5 December 2016 (UTC)Reply

How to create automatic link to Special:Drilldown? [solved]

I would like to be able to have the output of a Cargo query, for a particular field, contain an automatically-created link to the Special:Drilldown page for that field. I can get it to work with CONCAT, except when there is a space character in the field contents. The space character breaks the URL, and I can't get {{urlencode:<field>}} to work within a Cargo query. Thanks in anticipation. Jonathan3 (talk) 00:36, 5 December 2016 (UTC)Reply

I think I've got an answer: add $wgCargoAllowedSQLFunctions[] = 'REPLACE'; to LocalSettings.php, and use CONCAT("[http://www.example.com/Special:Drilldown/Contact?<fieldname>=", REPLACE(<fieldname>," ","_"), " ", <fieldname>, "]")=<fieldname> in the Cargo query. Unless there is a better way? Jonathan3 (talk) 01:00, 5 December 2016 (UTC)Reply
Great. I don't know of a better way. I should probably add 'REPLACE' to the default value of that array. Yaron Koren (talk) 01:45, 5 December 2016 (UTC)Reply

Excluding some fields from Special:Drilldown

I would like to be able to exclude some fields from Special:Drilldown but still have them show up on Special:ViewTable. The "hidden" parameter would hide them from both. Is there another parameter to do this? Thanks Jonathan3 (talk) 13:28, 8 December 2016 (UTC)Reply

No. Maybe "hidden" shouldn't hide the field from Special:ViewTable... I forgot that I had set it up that way. Yaron Koren (talk) 15:08, 8 December 2016 (UTC)Reply

Changing name of Special:Drilldown

For a non-technical audience this name would mean very little. Is there any way to change it to something else, or provide an alias, e.g. Special:Browse? Thanks Jonathan3 (talk) 13:35, 8 December 2016 (UTC)Reply

You might just need to edit the page MediaWiki:Drilldown. Yaron Koren (talk) 15:09, 8 December 2016 (UTC)Reply
Thanks. That changes the page title. Is there any way to change the URL? I guess not so easily... Jonathan3 (talk) 22:25, 9 December 2016 (UTC)Reply

Wikitext fields not rendered correctly by formatting templates

When our queries return wikitext fields directly, HTML-type formatting renders correctly, but when the query uses a formatting template, only strict wiki markup displays correctly. For example, to get text to display as bold, we must use triple apostrophes; if we use <b>, the rendered page displays the HTML markup as typed; similarly, a typed special character like an angle bracket displays correctly, but HTML entity markup does not. We cannot use HTML markup for lists, nor formatting for which there is no strict wiki equivalent, such as <code>, <pre> or <sup>. Is this a bug or a limitation of wikitext in Cargo (ie., HTML parsing does not survive passthrough to a formatting template)? --Bgrenon (talk) 14:07, 13 December 2016 (UTC)Reply

It's not a bug - that's deliberate behavior on the part of Cargo, because, yes, the MediaWiki parser couldn't otherwise handle that complexity of parsing, unfortunately. Yaron Koren (talk) 03:13, 14 December 2016 (UTC)Reply

Neither master nor the REL1_27 branch work with MW 1.27

Running MediaWiki 1.27 on Cargo's REL1_27 branch from Git, all queries using {{#cargo_query}}, Special:ViewData, or the Lua API return the expected number of results, but the results themselves are empty. For instance, a {{#cargo_query}} with two columns that returns four results containing strings will output a two-column table, but every row is blank and contains nothing.

When switching to Cargo's master branch, all maintenance scripts start to fail with:

PHP Fatal error:  Uncaught Error: Call to undefined method CargoRecreateData::requireExtension() in /var/www/wiki/extensions/Cargo/maintenance/cargoRecreateData.php:37
Stack trace:
#0 /var/www/wiki/maintenance/doMaintenance.php(48): CargoRecreateData->__construct()
#1 /var/www/wiki/extensions/Cargo/maintenance/cargoRecreateData.php(137): require_once('/var/www/wiki/m...')
#2 {main}
  thrown in /var/www/wiki/extensions/Cargo/maintenance/cargoRecreateData.php on line 37

To resolve both issues, I had to reset the master branch to commit 38b3cbad (git reset --hard 38b3cbad; this is the commit prior to implementing requireExtension() in the maintenance scripts, which addresses bug T152139. requireExtension() is not available to 1.27.). -71.36.99.196 16:44, 22 December 2016 (UTC)Reply

Sorry about that! Those lines were not added by me, but then again I didn't check them either after they were addded. I just checked in a fix, so now requireExtension() is called only if it's defined already. Yaron Koren (talk) 20:57, 22 December 2016 (UTC)Reply

Error upgrading to latest Cargo master

Hi Yaron

I just tried to upgrade to the latest master and when I access a page displaying a caalendar I get the following erro:

Warning: require(/var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/extensions/Cargo//formats/CargoCalendarFormat.php): failed to open stream: No such file or directory in /var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/includes/AutoLoader.php on line 90

Warning: require(/var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/extensions/Cargo//formats/CargoCalendarFormat.php): failed to open stream: No such file or directory in /var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/includes/AutoLoader.php on line 90

Fatal error: require(): Failed opening required '/var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/extensions/Cargo//formats/CargoCalendarFormat.php' (include_path='.:/opt/plesk/php/5.6/share/pear') in /var/www/vhosts/cmswiki.farm/httpdocs/x/mw-1.26/includes/AutoLoader.php on line 90

Other pages seem to be working OK. I wondered if I had done something wrong?

Many thanks Duncan, 29th Dec 2016

Does that file exist? (I doubt that double-slash is an issue, by the way, but who knows.) Yaron Koren (talk) 02:37, 30 December 2016 (UTC)Reply
Hi Yaron, you are right the file wasn't in the directory.

Question about date sorting with Dynamic Tables

Hi Yaron

I have the following query which I wish to sort by the End date in ascending order:

{{#cargo_query:
|tables=Assignments,Events,Page_properties,_pageData 
|join on=Assignments._pageName=Page_properties._pageName,Assignments._pageName=_pageData._pageName,Assignments._pageName=Events._pageName 
|fields=Assignments._pageName=Title,Page_properties.Description,Events.Event_Start_Date_Time=Start,DATE_FORMAT(Events.Event_End_Date_Time,'%D %M %Y')=End
|where={{Holds Individual Assignments|UserNames={{PAGENAME}} }} OR {{Holds Group Assignments|GroupNames={{Get Users Groups|UsersPageNames={{PAGENAME}} }} }}
|group by=Assignments._pageName
|order by=End ASC
|format=dynamic table
}}

However it seem to treat the End Date as a text field rather than date field and sort by the leading character. If I replace the End in the 'order by' clause in the above with the Start column, the query sorts on the start date as expected. The difference between the two date columns is that the End column uses the DATE_FORMAT command. I wondered if this causes 'order by' to treat the field as text rather than a date?

If this is the correct behaviour, can you suggest a way to get the table to sort by the date value rather than the text value on a formatted date column?

Many thanks

Duncan 29th Dec 2016

"dynamic table" does it own sorting (as of very recently), so it's probably a bug in its sorting code. Yaron Koren (talk) 02:39, 30 December 2016 (UTC)Reply
Okay, I just looked into it, and yes - I'm pretty sure it's because the DATE_FORMAT call makes the display treat the field as a string instead of as a date. This is a tricky one - normally I'd suggest just changing the "order by" value to use the actual date field, but that won't help here because the "dynamic table" format can't sort on a field that is not being displayed (as far as I know). Short of a change to the Cargo code, your only option might be to remove that date formatting. Yaron Koren (talk) 05:44, 30 December 2016 (UTC)Reply

Variable in a Cargo data query

I created a template page on my Mediawiki installation and implemented a query using Cargo. In my query I defined a "where" clause, which checks if a field is identical to a certain variable. The variable "RandomCity" was set on the article page that calls the template. Here is the code in the template:

{{#cargo_query: tables=Cities |fields=_pageName,population |where=_pageName="{{{RandomCity}}}" }}

Unfortunately, the variable does not insert its value. Is there a way to fix this? --94.216.202.80 02:20, 30 December 2016 (UTC)Reply

This works fine for me. How do you know it's not working? Yaron Koren (talk) 02:46, 30 December 2016 (UTC)Reply
I checked it and noticed, that there was a Typo, where I set {{{RandomCity}}} to "[[London]]". Due to the brackets there was no result. Thanks. --94.216.202.80 02:59, 30 December 2016 (UTC)Reply