Advertisement
Guest User

Untitled

a guest
Jun 11th, 2012
704
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.76 KB | None | 0 0
  1. <?php
  2.  
  3.     /*
  4.      * Script:    DataTables server-side script for PHP and MySQL
  5.      * Copyright: 2010 - Allan Jardine
  6.      * License:   GPL v2 or BSD (3-point)
  7.      */
  8.  
  9.     // BETA - Modified Chris Wright 06/12
  10.  
  11.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  12.      * Easy set variables
  13.      */
  14.  
  15.     /* Array of database columns which should be read and sent back to DataTables. Use a space where
  16.      * you want to insert a non-database field (for example a counter or static image)
  17.      */
  18.     $aColumns = array('hit.timestamp', 'hit.id', 'config.Name', 'hit.meter_id','levels.LevelName','pos.sm_pos','hit.hit_value'  );
  19.  
  20.     /* Indexed column (used for fast and accurate table cardinality) */
  21.     $sIndexColumn = "hit.id";
  22.  
  23.     /* DB table to use */
  24.     $sTable = "hit
  25.       INNER JOIN config
  26.               ON hit.id = config.id
  27.       INNER JOIN levels
  28.               ON hit.meter_id = levels.id
  29.       INNER JOIN POS
  30.               ON pos.id = hit.id
  31.       INNER JOIN controllers
  32.               ON pos.controller_id = controllers.id";
  33.  
  34.     /* Database connection information */
  35.     $gaSql['user']       = "";
  36.     $gaSql['password']   = "";
  37.     $gaSql['db']         = "";
  38.     $gaSql['server']     = "localhost";
  39.  
  40.  
  41.     /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  42.      * If you just want to use the basic configuration for DataTables with PHP server-side, there is
  43.      * no need to edit below this line
  44.      */
  45.  
  46.     function fatal_error ( $sErrorMessage = '' )
  47.     {
  48.         /* CW 06/2012
  49.          * Return HTTP 500 to the client with an error message in the body
  50.          */
  51.         header( $_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error' );
  52.         die( $sErrorMessage );
  53.     }
  54.  
  55.     function parse_mysql_field ($sField)
  56.     {
  57.         /* CW 06/2012
  58.          * Takes as string definition of a MySQL database field and return an array describing
  59.          * the column name, table name (if present) and alias name (if present)
  60.          */
  61.         $sRegex =
  62.              // Delimiter
  63.             '/'
  64.             // Leading white space
  65.           . '^\s*'
  66.             // Table name
  67.           . '(?:(?P<table>(?:`[^`]+`|[\w$]+))\.)?'
  68.             // Column name
  69.           . '(?P<column>(?:`[^`]+`|[\w$]+))'
  70.             // Column alias
  71.           . '(?:\s+as\s+(?P<alias>(?:(?P<aliasquotetype>[`\'"]?)[\w$]+\4|[\w$]+)))?'
  72.             // Delimiter/no case
  73.           . '/i';
  74.         preg_match($sRegex, $sField, $aMatches);
  75.  
  76.         $aResult = array();
  77.  
  78.         if ( $aMatches['table'] != '')
  79.         {
  80.             $aResult['table'] = trim( $aMatches['table'], '`' );
  81.         }
  82.         $aResult['column'] = trim( $aMatches['column'], '`' );
  83.         if ( !empty( $aMatches['alias'] ) )
  84.         {
  85.             if ( !empty( $aMatches['aliasquotetype'] ) )
  86.             {
  87.                 $aResult['alias'] = trim( $aMatches['alias'], $aMatches['aliasquotetype'] );
  88.             }
  89.             else
  90.             {
  91.                 $aResult['alias'] = $aMatches['alias'];
  92.             }
  93.         }
  94.  
  95.         return $aResult;
  96.  
  97.     }
  98.  
  99.     if ( ! function_exists( 'json_encode' ) )
  100.     {
  101.         function json_encode ($mData)
  102.         {
  103.             /* CW 06/2012
  104.              * Replacement for native PHP json_enocde() when unavailable
  105.              */
  106.             $bIsObject = FALSE;
  107.             switch (TRUE) {
  108.                 case $mData === NULL: return 'null';
  109.                 case is_bool($mData): return $mData ? 'true' : 'false';
  110.                 case is_int($mData) || is_float($mData): return $mData;
  111.                 case is_string($mData): return '"' . addcslashes($mData, '"\\') . '"';
  112.                 case is_object($mData):
  113.                     $bIsObject = TRUE;
  114.                     $mData = get_object_vars($mData);
  115.                 case is_array($mData):
  116.                     $i = 0;
  117.                     foreach ($mData as $mKey => $mValue)
  118.                     {
  119.                         if ($mKey !== $i++)
  120.                         {
  121.                             $bIsObject = TRUE;
  122.                             break;
  123.                         }
  124.                     }
  125.                     $iLength = count($mData);
  126.                     if ($bIsObject)
  127.                     {
  128.                         foreach ($mData as $sKey => $mValue)
  129.                         {
  130.                             $mData[$sKey] = json_encode((string) $sKey) . ':' . json_encode($mValue);
  131.                         }
  132.                         return '{' . implode ( ',', $mData ) . '}';
  133.                     }
  134.                     else
  135.                     {
  136.                         foreach ($mData as $iKey => $mValue)
  137.                         {
  138.                                $mData[$iKey] = json_encode($mValue);
  139.                         }
  140.                         return '[' . implode ( ',', $mData ) . ']';
  141.                     }
  142.             }
  143.         }
  144.     }
  145.  
  146.     /*
  147.      * MySQL connection
  148.      */
  149.     if ( ! $gaSql['link'] = mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password']  ) )
  150.     {
  151.         /* CW 06/2012
  152.          * http://www.phpfreaks.com/blog/or-die-must-die
  153.          * Send a meaningful HTTP response code on the event of failure - especially since
  154.          * the client is expecting a JSON response on success
  155.          */
  156.         fatal_error( 'Could not open connection to server' );
  157.     }
  158.  
  159.     if ( ! mysql_select_db( $gaSql['db'], $gaSql['link'] ) )
  160.     {
  161.         /* CW 06/2012
  162.          * Giving the database name out is unnecessary information and may provide
  163.          * the haxxors with that missing piece of information that let's them bring
  164.          * the whole site down
  165.          */
  166.         fatal_error( 'Could not select database ' );
  167.     }
  168.  
  169.     /* CW 06/2012
  170.      * Number of columns cached to prevent loop condition on count()
  171.      */
  172.     $iNumCols = count($aColumns);
  173.  
  174.     /* CW 06/2012
  175.      * Create list of columns for use outside field list
  176.      * This allows the use of identifier aliases in $aColumns, and quotes identifiers
  177.      * to avoid collisions with MySQL reserved words
  178.      */
  179.     $aClauseColumns = array();
  180.     for ( $i = 0 ; $i < $iNumCols ; $i++ )
  181.     {
  182.         /* Parse column string */
  183.         $aField = parse_mysql_field( $aColumns[$i] );
  184.  
  185.         /* Create properly quoted strings from parsed values */
  186.         $sClauseCol = $sFieldCol = $sTableName = $sColumnName = $sColumnAlias = '';
  187.         if ( !empty( $aField['table'] ) )
  188.         {
  189.             $sTableName = '`' . trim( $aField['table'], '`' ) . '`.';
  190.             $sClauseCol .= $sTableName;
  191.             $sFieldCol .= $sTableName;
  192.         }
  193.         $sColumnName = '`' . trim( $aField['column'], '`' ) . '`';
  194.         $sClauseCol .= $sColumnName;
  195.         $sFieldCol .= $sColumnName;
  196.         if ( !empty( $aField['alias'] ) )
  197.         {
  198.             $sFieldCol .= ' AS `' . $aMatches['alias'] . '`';
  199.         }
  200.         $aClauseColumns[$i] = $sClauseCol;
  201.         $aColumns[$i] = $sFieldCol;
  202.     }
  203.  
  204.     /*
  205.      * Paging
  206.      */
  207.     $sLimit = "";
  208.     if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
  209.     {
  210.         /* CW 06/2012
  211.          * @mysql_real_escape_string() is for STRINGS!!
  212.          * LIMIT parameters are integers - casting to int is quicker than
  213.          * ...escape_string() and will not produce syntactically invalid queries
  214.          */
  215.         $sLimit = "LIMIT ".((int) $_GET['iDisplayStart'] ).", ".((int) $_GET['iDisplayLength'] );
  216.     }
  217.  
  218.  
  219.     /*
  220.      * Ordering
  221.      */
  222.     /* CW 06/2012
  223.      * Using an array removes the nasty string initialisation that may end up
  224.      * being reversed. Also removes the need to substr_replace()
  225.      */
  226.     $sOrder = "";
  227.     $aOrder = array();
  228.     if ( isset( $_GET['iSortCol_0'] ) )
  229.     {
  230.         /* CW 06/2012
  231.          * The intval() call is completely unnecessary, type coercion will sort it
  232.          * out for us. However if we want to force the type, we should do it *before*
  233.          * the loop since the result will be the same every time.
  234.          */
  235.         $iSortingCols = (int) $_GET['iSortingCols'];
  236.         for ( $i = 0 ; $i < $iSortingCols ; $i++ )
  237.         {
  238.             if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
  239.             {
  240.                 /* CW 06/2012
  241.                  * @mysql_real_escape_string() is for STRINGS!!
  242.                  * MySQL keywords cannot be escaped in a meaningful way. Use string
  243.                  * comparisons instead.
  244.                  */
  245.                 $sSortDirection = (strtoupper( trim( $_GET['sSortDir_'.$i] ) ) == 'DESC') ? 'DESC' : 'ASC';
  246.                 $aOrder[] = $aClauseColumns[ intval( $_GET['iSortCol_'.$i] ) ]." ".$sSortDirection;
  247.             }
  248.         }
  249.  
  250.         if ( count( $aOrder ) > 0)
  251.         {
  252.             $sOrder = "ORDER BY " . implode(', ', $aOrder);
  253.         }
  254.     }
  255.  
  256.  
  257.     /*
  258.      * Filtering
  259.      * NOTE this does not match the built-in DataTables filtering which does it
  260.      * word by word on any field. It's possible to do here, but concerned about efficiency
  261.      * on very large tables, and MySQL's regex functionality is very limited
  262.      */
  263.     /* CW 06/2012
  264.      * Array use for same reasons as in Ordering: section
  265.      */
  266.     $sWhere = "";
  267.     $aWhereOr = array(); //
  268.     if ( isset( $_GET['sSearch'] ) && $_GET['sSearch'] !== '' )
  269.     {
  270.         for ( $i = 0 ; $i < $iNumCols ; $i++ )
  271.         {
  272.             if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" )
  273.             {
  274.                 $aWhereOr[] = $aClauseColumns[$i]." LIKE '%".@mysql_real_escape_string( $_GET['sSearch'] )."%'";
  275.             }
  276.         }
  277.         if ( count($aWhereOr) > 0 )
  278.         {
  279.             $sWhere .= "WHERE (" . implode(' OR ', $aWhereOr) . ')';
  280.         }
  281.     }
  282.  
  283.     /* Individual column filtering */
  284.     /* CW 06/2012
  285.      * Array use for same reasons as in Ordering: section
  286.      */
  287.     $aWhereAnd = array();
  288.     for ( $i = 0 ; $i < $iNumCols ; $i++ )
  289.     {
  290.         if ( isset($_GET['bSearchable_'.$i]) && $_GET['bSearchable_'.$i] == "true" && isset( $_GET['sSearch_'.$i] ) && $_GET['sSearch_'.$i] !== '' )
  291.         {
  292.             $aWhereAnd[] = $aClauseColumns[$i]." LIKE '%".@mysql_real_escape_string($_GET['sSearch_'.$i])."%'";
  293.         }
  294.     }
  295.     if ( count($aWhereAnd) > 0 )
  296.     {
  297.         if ($sWhere == "")
  298.         {
  299.             $sWhere .= "WHERE ";
  300.         }
  301.         else
  302.         {
  303.             $sWhere .= " AND ";
  304.         }
  305.         $sWhere .= implode(' AND ', $aWhereAnd);
  306.     }
  307.  
  308.  
  309.     /*
  310.      * SQL queries
  311.      * Get data to display
  312.      */
  313.     $sQuery = "
  314.        SELECT SQL_CALC_FOUND_ROWS " . implode( ", ", $aColumns ) . "
  315.        FROM $sTable
  316.        $sWhere
  317.        $sOrder
  318.        $sLimit
  319.    ";
  320.     $rResult = mysql_query( $sQuery, $gaSql['link'] )
  321.         /* CW 06/2012
  322.          * Showing mysql_error() to the outside world is a BIG no-no
  323.          */
  324.         or fatal_error( 'MySQL Error: ' . mysql_errno() );
  325.  
  326.     /* Data set length after filtering */
  327.     $sQuery = "
  328.        SELECT FOUND_ROWS()
  329.    ";
  330.     $rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] )
  331.         or fatal_error( 'MySQL Error: ' . mysql_errno() );
  332.     $iFilteredTotal = mysql_result( $rResultFilterTotal, 0, 0 );
  333.     mysql_free_result( $rResultFilterTotal );
  334.  
  335.     /* Total data set length */
  336.     $sQuery = "
  337.        SELECT COUNT(".$sIndexColumn.")
  338.        FROM $sTable
  339.    ";
  340.     $rResultTotal = mysql_query( $sQuery, $gaSql['link'] )
  341.         or fatal_error( 'MySQL Error: ' . mysql_errno() );
  342.     $iTotal = mysql_result( $rResultTotal, 0, 0 );
  343.     mysql_free_result( $rResultTotal );
  344.  
  345.  
  346.     /*
  347.      * Output
  348.      */
  349.     $aOutput = array
  350.     (
  351.         "sEcho" => (int) $_GET['sEcho'],
  352.         "iTotalRecords" => $iTotal,
  353.         "iTotalDisplayRecords" => $iFilteredTotal,
  354.         "aaData" => array()
  355.     );
  356.  
  357.     if ( mysql_num_rows( $rResult ) > 0 )
  358.     {
  359.  
  360.         /* CW 06/2012
  361.          * Find the position of the 'version' column if one was defined
  362.          */
  363.         $aCols = array_keys( mysql_fetch_assoc( $rResult ) );
  364.         mysql_data_seek($rResult, 0);
  365.         $iVersionCol = array_search( 'version', $aCols );
  366.  
  367.         /* CW 06/2012
  368.          * Using _fetch_row() gives us the array in the format we want with no
  369.          * messing about. This will be faster and more memory efficient
  370.          */
  371.         while ( $aRow = mysql_fetch_row( $rResult ) )
  372.         {
  373.             if ( $iVersionCol !== FALSE && $aRow[$iVersionCol] == '0')
  374.             {
  375.                 /* CW 06/2012
  376.                  * Only modify the data if 'version' is defined
  377.                  */
  378.                 $aRow[$iVersionCol] = '-';
  379.             }
  380.             $aOutput['aaData'][] = $aRow;
  381.         }
  382.     }
  383.  
  384.     echo json_encode( $aOutput );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement