0
votes

In Datatables using server side processing, is it possible to use column alias when specifying the columns?

At the moment this works fine with:

$aColumns = array( 'datetime','username', 'user_ip', 'company', 'action' );

but I would like to change the format of the date using date format in MySQL so, in effect, I want to use:

$aColumns = array( 'DATE_FORMAT(datetime, "%d/%m/%Y - %H:%i:%s") as newdate';'username'; 'user_ip';'company'; 'action' );

The problem is that the alias has a comma and the aColumns array is comma seperated so it breaks when later, for example, it comes to:

$sQuery = "
    SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
    FROM   $sTable
    $sWhere
    $sOrder
    $sLimit
";

Is there a way I can use the alias rather than the original value? Even simply changing the select statement does not work as aColumns is used throughout the script hence it needs that value to be set correctly

Thanks

1

1 Answers

2
votes

Yes. I actually just struggled with this issue myself. Because the JSON output is determined through counting the amount of columns in the array, and because of the imploding array, you have to add your column alias to $sQuery instead of the $aColumns array. So you'll actually have one less column in your $aColumns array than you'll need. For example, in mine, I needed an alias called total created from multiplying price and qty. So I put all my unaliased columns in the $aColumns array, like this:

$aColumns = array( 'purchaseID', 'dateOfOrder', 'productID', 'price', 'QTY');

But then, in the $sQuery string that concatenates all the things necessary to create the proper query string, I added my column alias between the implode and FROM. Don't forget to put a comma after the implode though, because it doesn't add it for you. The original $sQuery string looks like this:

 $sQuery = "
    SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
    FROM   `$sTable`
    $sWhere
    $dateSql
    $sOrder
    $sLimit
";

But mine, with the column alias added, looks like this:

$sQuery = "
    SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
    , `price` * `QTY` AS `total` FROM   `$sTable`
    $sWhere
    $dateSql
    $sOrder
    $sLimit
";

Finally, the last thing you have to do is alter the actual JSON output to make sure your extra column is accounted for in the FOR loop at the end right before the json_encode, because it inserts items into the $row array, which is what becomes 'aaData' (the returned row data), based on how many columns you've specified in the $aColumns array, and because you left out any you've aliased, the count will be wrong, and you will get an error that looks something like 'requested unknown parameter from data source row'. The original FOR loop looks like this:

while ( $aRow = mysql_fetch_array( $rResult ) )
{
    $row = array();
    for ( $i=0 ; $i<count($aColumns) ; $i++ )
    {
        if ( $aColumns[$i] == "version" )
        {
            /* Special output formatting for 'version' column */
            $row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
        }
        else if ( $aColumns[$i] != ' ' )
        {
            /* General output */
            $row[] = $aRow[ $aColumns[$i] ];
        }
    }
    $output['aaData'][] = $row;
}

Like I said, this FOR loop works based off the COUNT of the $aColumns array, and since I've added an alias, it's going to cut my results short. It's not going to return the last element in the array containing the returned columns, so I'm going to alter the code to look like this:

for ( $i=0 ; $i<count($aColumns) + 1; $i++ )
    {
        if ($i < count($aColumns)){
            if ( $aColumns[$i] == "version" )
            {
                /* Special output formatting for 'version' column */
                $row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
            }
            else if ( $aColumns[$i] != ' ' )
            {
                /* General output */
                $row[] = $aRow[ $aColumns[$i] ];
            }
        }
        else {
            $row[] = $aRow['total'];
        }

    }
    $output['aaData'][] = $row;
}

All I changed was the counter condition from $i<count($aColumns) to $i<count($aColumns) + 1, because my alias makes the column count one higher than what's in the array. And I've added a wrapping if-else that just says that if the counter, $i, is higher than the number of columns I've specified in the $aColumns array, then we've added all the columns in the array to the output data, so because I only added one extra alias column, then that means I can go ahead and just add that to the $row array, which contains all the output data from the returned rows.

You can actually add in as many aliased columns as you need, you just need to scale the code accordingly. Hope this helps!