<?php

  # load modules
  $noSessionStart = true; // don't call session start (not needed for viewers)
  $libDir         = pathinfo(__FILE__, PATHINFO_DIRNAME);
  require_once "$libDir/init.php";


//
function getListRows($options) {
  global $MYSQLI, $TABLE_PREFIX;
  $viewerName = "List Viewer ({$options['tableName']})";

  // error checking
  $requiredOptions = array('tableName');
  $validOptions    = array('tableName', 'titleField', 'perPage', 'where', 'orderBy', 'viewerUrl', 'pageNum', 'useSeoUrls');
  $errors          = _getOptionErrors($requiredOptions, $validOptions, $options);
  if ($errors) { die("$viewerName errors<br/>\n$errors"); }

  // set defaults
  if (!@$options['pageNum'])   { $options['pageNum']   = getNumberFromEndOfUrl(); }
  if (!@$options['pageNum'])   { $options['pageNum']   = "1"; } // if no number on end of url, set to 1
  if (!@$options['perPage'])   { $options['perPage']   = 10; }
  if (!@$options['viewerUrl']) { $options['viewerUrl'] = "No_viewerUrl_value_specified_in_options"; }

  // set url delimiter for SEO urls
  $urlDelimiter = (@$options['useSeoUrls']) ? "/" : "?";
  if (@$options['useSeoUrls'] && @$options['viewerUrl'] && !preg_match("|[/]|", $options['viewerUrl'])) {
    die("$viewerName: You must set 'viewerUrl' to be an absolute url (example: '/path/to/viewer.php') to use search engine friendly urls!");
  }


  # create query
  $fullTableName    = getTableNameWithPrefix($options['tableName']);
  $escapedTableName = $MYSQLI->escape_string($fullTableName);
  $where            = _getWhereConditions($escapedTableName, @$options['where']);
  $orderBy          = (@$options['orderBy']) ? "ORDER BY {$options['orderBy']}" : "";
  $offset           = ($options['pageNum']-1) * $options['perPage'];
  $limit            = "LIMIT " .$MYSQLI->escape_string($options['perPage']). " OFFSET " .$MYSQLI->escape_string($offset);
  $query            = "SELECT SQL_CALC_FOUND_ROWS * FROM `$escapedTableName` $where $orderBy $limit";

  # execute query
  $result     = $MYSQLI->query($query) or die("$viewerName: MySQL Error: ". htmlspecialchars($MYSQLI->error) . "\n");
  $rows       = array();
  while ($record = $result->fetch_assoc()) {
    $extraUrlDetails = "";
    if (@$options['titleField']) {
      $extraUrlDetails = "";
      if (!array_key_exists($options['titleField'], $record)) {
        $extraUrlDetails = "Unknown_fieldname_specified_for_titleField_option/";
      }
      else {
        $extraUrlDetails = preg_replace('/[^a-z0-9\.\-\_]+/i', '_', @$record[$options['titleField']]);
        if ($extraUrlDetails) { $extraUrlDetails .= "-"; }
      }
    }
    $record['_link'] = $options['viewerUrl'] . $urlDelimiter . $extraUrlDetails . $record['num'];

    array_push($rows, $record);
  }

  # get record count
  $countResults = $MYSQLI->query("SELECT FOUND_ROWS()") or die("$viewerName: MySQL Error: {$MYSQLI->error}\n");
  $countRow     = $countResults->fetch_row();
  $totalRecords = (int) $countRow[0];

  # get list details
  $listDetails = array();
  $listDetails['totalRecords']  = $totalRecords;
  $listDetails['perPage']       = $options['perPage'];
  $listDetails['totalPages']    = ($totalRecords >= 1) ? ceil($totalRecords / $options['perPage']) : 1;
  $listDetails['page']          = ($options['pageNum'] > 0) ? min($options['pageNum'], $listDetails['totalPages']) : 1;
  $listDetails['prevPage']      = ($listDetails['page'] > 1) ? $listDetails['page']-1 : '';
  $listDetails['nextPage']      = ($listDetails['page'] < $listDetails['totalPages']) ? $listDetails['page']+1 : '';
  $listDetails['prevPageLink']  = "{$_SERVER['PHP_SELF']}{$urlDelimiter}page{$listDetails['prevPage']}";
  $listDetails['nextPageLink']  = "{$_SERVER['PHP_SELF']}{$urlDelimiter}page{$listDetails['nextPage']}";

  $listDetails['noRecordsFound'] = empty($rows) && $listDetails['page'] == 1;
  $listDetails['invalidPageNum'] = empty($rows) && $listDetails['page'] > 1;
  $listDetails['firstPageLink']  = "{$_SERVER['PHP_SELF']}{$urlDelimiter}page1";
  $listDetails['lastPageLink']   = "{$_SERVER['PHP_SELF']}{$urlDelimiter}" . $listDetails['totalPages'];

  return array($rows, $listDetails);
}



//
function getRecord($options) {
  global $MYSQLI, $TABLE_PREFIX;
  $viewerName = "Page Viewer ({$options['tableName']})";

  // error checking
  $requiredOptions = array('tableName');
  $validOptions    = array('tableName', 'recordNum', 'where');
  $errors          = _getOptionErrors($requiredOptions, $validOptions, $options);
  if ($errors) { die("$viewerName errors<br/>\n$errors"); }

  // set defaults
  $schema = loadSchema($options['tableName']);
  if (!@$options['recordNum'])          { $options['recordNum'] = getNumberFromEndOfUrl(); }
  if (!@$options['recordNum'])          { $options['recordNum'] = "1"; }  // if no number on end of url, set to 1
  if (@$schema['menuType'] == 'single') { $options['recordNum'] = "1"; }  // always load record 1 for single menus

  // get where condition
  $whereConditions  = '';
  $escapedRecordNum = $MYSQLI->escape_string( (int) $options['recordNum'] );
  if ($options['where']) { $whereConditions = $options['where']; }
  else                   { $whereConditions = "num = '$escapedRecordNum'"; }

  // get record
  $fullTableName    = getTableNameWithPrefix($options['tableName']);
  $escapedTableName = $MYSQLI->escape_string($fullTableName);
  $where            = _getWhereConditions($escapedTableName, $whereConditions);
  $query            = "SELECT * FROM `$escapedTableName` $where LIMIT 0, 1";
  $result           = $MYSQLI->query($query) or die("$viewerName: MySQL Error: ". htmlspecialchars($MYSQLI->error) . "\n");
  $record           = $result->fetch_assoc();

  // define upload fields
  if ($record) {
    foreach ($schema as $fieldname => $fieldSchema) {
      if (@$fieldSchema['type'] != 'upload') { continue; }  // skip all but upload fields
      $record[$fieldname] = "Use getUploads() function to list uploads (See code generator).\n";
    }
  }

  //
  return $record;
}


//
function getUploads($tableName, $fieldName, $recordNum) {
  global $TABLE_PREFIX, $MYSQLI;
  $uploads = array();
  // error checking
  if (!$tableName) { die(__FUNCTION__ . ": no 'tableName' value specified!"); }
  if (!$fieldName) { die(__FUNCTION__ . ": no 'fieldName' value specified!"); }
  if (!$recordNum) { die(__FUNCTION__ . ": no 'recordNum' value specified!"); }

  // get record uploads
  $tableNameWithoutPrefix = getTableNameWithoutPrefix($tableName);
  $query   = "   SELECT * FROM {$TABLE_PREFIX}uploads ";
  $query  .= "    WHERE tableName = '" .$MYSQLI->escape_string($tableNameWithoutPrefix). "' AND ";
  $query  .= "          fieldName = '" .$MYSQLI->escape_string($fieldName). "' AND";
  $query  .= "          recordNum = '" .$MYSQLI->escape_string($recordNum). "'";
  $query  .= " ORDER BY createdTime";
  $result  = $MYSQLI->query($query) or die("MySQL Error: ". htmlspecialchars($MYSQLI->error) . "\n");

  //
  while ($upload = $result->fetch_assoc()) {
    $upload['filename']     = pathinfo($upload['filePath'], PATHINFO_BASENAME);
    $upload['extension']    = pathinfo($upload['filePath'], PATHINFO_EXTENSION);
    $upload['isImage']      = preg_match("/\.(gif|jpg|jpeg|png)$/i", $upload['filePath']);
    $upload['hasThumbnail'] = $upload['isImage'] && $upload['thumbUrlPath'];

    array_push($uploads, $upload);
  }

  return $uploads;
}

// returns page number from url.  matches: view.php/anythinghere-####
function getNumberFromEndOfUrl() {
  $recordNum = 0;
  $urlDataFields = array(@$_SERVER["PATH_INFO"], $_SERVER["QUERY_STRING"]);
  foreach ($urlDataFields as $urlData) {
    if (preg_match("/\D*(\d+)$/", $urlData, $matches)) {
      $recordNum = $matches[1];
      break;
    }
  }
  return $recordNum;
}


//
function _getWhereConditions($tableName, $extraConditions) {
  global $MYSQLI;

  $where            = "";
  $schema           = loadSchema($tableName);
  $conditions       = array();

  if ($extraConditions)                 { array_push($conditions, "($extraConditions)"); }
  if (@$schema['hidden'])               { array_push($conditions, "hidden = 0"); }
  if (@$schema['autoPublishStartDate']) { array_push($conditions, "(ISNULL(autoPublishStartDate) OR autoPublishStartDate <= NOW())"); }
  if (@$schema['autoPublishEndDate'])   {
    $thisCondition  = "ISNULL(autoPublishEndDate) OR autoPublishEndDate >= NOW()";  // NULL end date or future end date
    if (@$schema['autoPublishNeverExpires']) { $thisCondition .= " OR autoPublishNeverExpires = 1"; } // never expires checked
    array_push($conditions, "($thisCondition)");
  }
  if ($conditions) {
    $where = "WHERE " . implode(" AND ", $conditions);
  }

  return $where;
}


// return errors for missing required options and invalid option names
function _getOptionErrors($requiredOptions, $validOptions, $options) {
  $errors = "";

  // check for required fields
  foreach ($requiredOptions as $requiredOptionName) {
    if (!$options[$requiredOptionName]) { $errors .= "No '$requiredOptionName' value specified in options.<br/>\n"; }
  }

  // check for invalid options
  foreach ($options as $optionName => $optionValue) {
    if (!in_array($optionName, $validOptions)) {
      $validOptionsAsCSV = implode(', ', $validOptions);
      $errors .= "Unknown option '$optionName' specified.  Valid option names are: ($validOptionsAsCSV)<br/>\n";
    }
  }

  return $errors;
}


?>
