Basic API and Authentication extensions.
这个提交包含在:
父节点
052b820b42
当前提交
9a3b44d73d
共有 12 个文件被更改,包括 1312 次插入 和 0 次删除
141
application/controllers/api.php
普通文件
141
application/controllers/api.php
普通文件
|
|
@ -0,0 +1,141 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class API extends CI_Controller {
|
||||
|
||||
// Do absolutely nothing
|
||||
function index()
|
||||
{
|
||||
//load the model and get results
|
||||
$this->load->model('logbook_model');
|
||||
$data['data'] = array();
|
||||
|
||||
// load the view
|
||||
//$this->load->view('layout/header');
|
||||
$this->load->view('api/index', $data);
|
||||
//$this->load->view('layout/footer');
|
||||
}
|
||||
|
||||
// FUNCTION: search()
|
||||
// Handle search requests
|
||||
/*
|
||||
Okay, so here's how it works in a nutshell...
|
||||
|
||||
*******************************************************************
|
||||
Because this is effectively just a filter between the query string
|
||||
and a MySQL statement, if done wrong we're just asking for pain.
|
||||
|
||||
DO NOT alter any of the filtering statements without fully
|
||||
understanding what you're doing. CodeIgniter provides some
|
||||
protection against unwanted characters in the query string, but
|
||||
this should in no way be relied upon for safety.
|
||||
*******************************************************************
|
||||
|
||||
Example query:-
|
||||
.../search/query[Call~M0*(and)(Locator~I*(or)Locator~J*)]/limit[10]/fields[distinct(Call),Locator]/order[Call(asc)]
|
||||
|
||||
There's four parts to this query, separated with forward slashes. It's effectively a heavily-sanitised
|
||||
MySQL query, hence the hideous search and replace code blocks below.
|
||||
|
||||
FIELDS
|
||||
------
|
||||
Straightforward - input is sanitised and passed on - in the example, this ends up as "DISTINCT (Call),Locator",
|
||||
which is then the first argument to 'SELECT'
|
||||
|
||||
QUERY
|
||||
-----
|
||||
This forms the 'WHERE' clause.
|
||||
|
||||
* '(and)' and '(or)' are expanded out to ' AND ' and ' OR '
|
||||
* Parentheses are preserved
|
||||
* '~' is expanded out to ' LIKE '
|
||||
* '*' is translated to '%'
|
||||
* Values are encapsulated in quote marks
|
||||
|
||||
So in the example, this translates to "WHERE Call LIKE 'M0%' AND (Locator LIKE 'I%' OR Locator LIKE 'J%')"
|
||||
|
||||
ORDER
|
||||
-----
|
||||
Sanitised, so our example ends up as "ORDER BY Call ASC".
|
||||
|
||||
LIMIT
|
||||
-----
|
||||
Straightforward - what's between the square brackets is passed as an argument to 'LIMIT'
|
||||
|
||||
Finally, once this has been done, each field name is translated to the MySQL column name.
|
||||
*/
|
||||
|
||||
function search()
|
||||
{
|
||||
// Load the API and Logbook models
|
||||
$this->load->model('api_model');
|
||||
$this->load->model('logbook_model');
|
||||
|
||||
// Retrieve the arguments from the query string
|
||||
$arguments = $this->_retrieve();
|
||||
|
||||
// Call the parser within the API model to build the query
|
||||
$query = $this->api_model->parse($arguments);
|
||||
|
||||
// Execute the query, and retrieve the results
|
||||
$s = $this->logbook_model->api_search_query($query);
|
||||
$results = $s['results'];
|
||||
|
||||
// Cycle through the results, and translate between MySQL column names
|
||||
// and more friendly, descriptive names
|
||||
$a = 0;
|
||||
if($results->num_rows != 0)
|
||||
{
|
||||
foreach ($results->result() as $row) {
|
||||
$record = (array)$row;
|
||||
$r[$a]['rid'] = $a;
|
||||
while (list($key, $val) = each($record)) {
|
||||
$r[$a][$this->api_model->name($key)] = $val;
|
||||
}
|
||||
$a++;
|
||||
}
|
||||
// Add the result record to the main results array
|
||||
$data['data']['search_Result']['results'] = $r;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've got no results, so make this empty for completeness
|
||||
$data['data']['search_Result']['results'] = "";
|
||||
}
|
||||
|
||||
// Add some debugging information to the XML output
|
||||
$data['data']['queryInfo']['call'] = "search";
|
||||
$data['data']['queryInfo']['dbQuery'] = $s['query'];
|
||||
$data['data']['queryInfo']['numResults'] = $a;
|
||||
$data['data']['queryInfo']['executionTime'] = $s['time'];
|
||||
|
||||
// Load the XML output view
|
||||
$this->load->view('api/index', $data);
|
||||
}
|
||||
|
||||
// FUNCTION: _retrieve()
|
||||
// Pull the search query arguments from the query string
|
||||
private function _retrieve()
|
||||
{
|
||||
// This whole function could probably have been done in one line... if this was Perl.
|
||||
$arguments = array();
|
||||
|
||||
// Retrieve each arguments
|
||||
$query = preg_grep("/^query\[(.*)\]$/", $this->uri->segments);
|
||||
$limit = preg_grep("/^limit\[(.*)\]$/", $this->uri->segments);
|
||||
$order = preg_grep("/^order\[(.*)\]$/", $this->uri->segments);
|
||||
$fields = preg_grep("/^fields\[(.*)\]$/", $this->uri->segments);
|
||||
|
||||
// Strip each argument
|
||||
$arguments['query'] = substr(array_pop($query), 6);
|
||||
$arguments['query'] = substr($arguments['query'], 0, strlen($arguments['query']) - 1);
|
||||
$arguments['limit'] = substr(array_pop($limit), 6);
|
||||
$arguments['limit'] = substr($arguments['limit'], 0, strlen($arguments['limit']) - 1);
|
||||
$arguments['order'] = substr(array_pop($order), 6);
|
||||
$arguments['order'] = substr($arguments['order'], 0, strlen($arguments['order']) - 1);
|
||||
$arguments['fields'] = substr(array_pop($fields), 7);
|
||||
$arguments['fields'] = substr($arguments['fields'], 0, strlen($arguments['fields']) - 1);
|
||||
|
||||
// Return the arguments
|
||||
return $arguments;
|
||||
}
|
||||
}
|
||||
95
application/controllers/auth.php
普通文件
95
application/controllers/auth.php
普通文件
|
|
@ -0,0 +1,95 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Auth extends CI_Controller {
|
||||
|
||||
/* Displays all notes in a list */
|
||||
public function index()
|
||||
{
|
||||
$this->load->model('auth_model');
|
||||
|
||||
echo "<pre>";
|
||||
echo "Querying for user...\n";
|
||||
$u = $this->auth_model->get("m0vkga");
|
||||
print_r($u);
|
||||
echo "Test hashing\n";
|
||||
echo $this->auth_model->test();
|
||||
|
||||
}
|
||||
/*
|
||||
$this->load->model('note');
|
||||
$data['notes'] = $this->note->list_all();
|
||||
|
||||
$this->load->view('layout/header');
|
||||
$this->load->view('notes/main', $data);
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
|
||||
function add() {
|
||||
|
||||
$this->load->model('note');
|
||||
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$this->form_validation->set_rules('title', 'Note Title', 'required');
|
||||
$this->form_validation->set_rules('content', 'Content', 'required');
|
||||
|
||||
|
||||
if ($this->form_validation->run() == FALSE)
|
||||
{
|
||||
$this->load->view('layout/header');
|
||||
$this->load->view('notes/add');
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->note->add();
|
||||
|
||||
redirect('notes');
|
||||
}
|
||||
}
|
||||
|
||||
function view($id) {
|
||||
$this->load->model('note');
|
||||
|
||||
$data['note'] = $this->note->view($id);
|
||||
|
||||
// Display
|
||||
$this->load->view('layout/header');
|
||||
$this->load->view('notes/view',$data);
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
|
||||
function edit($id) {
|
||||
$this->load->model('note');
|
||||
$data['id'] = $id;
|
||||
|
||||
$data['note'] = $this->note->view($id);
|
||||
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$this->form_validation->set_rules('title', 'Note Title', 'required');
|
||||
$this->form_validation->set_rules('content', 'Content', 'required');
|
||||
|
||||
|
||||
if ($this->form_validation->run() == FALSE)
|
||||
{
|
||||
$this->load->view('layout/header');
|
||||
$this->load->view('notes/edit', $data);
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->note->edit();
|
||||
|
||||
redirect('notes');
|
||||
}
|
||||
}
|
||||
|
||||
function delete($id) {
|
||||
$this->load->model('note');
|
||||
$this->note->delete($id);
|
||||
|
||||
redirect('notes');
|
||||
}
|
||||
*/
|
||||
}
|
||||
319
application/models/api_model.php
普通文件
319
application/models/api_model.php
普通文件
|
|
@ -0,0 +1,319 @@
|
|||
<?php
|
||||
|
||||
class API_Model extends CI_Model {
|
||||
|
||||
function __construct()
|
||||
{
|
||||
// Call the Model constructor
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// FUNCTION: string name(string $column)
|
||||
// Converts a MySQL column name to a more friendly name
|
||||
function name($col)
|
||||
{
|
||||
if($this->_columnName[$col])
|
||||
{
|
||||
return $this->_columnName[$col]['Name'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: string description(string $column)
|
||||
// Returns the description for a MySQL column name
|
||||
function description($col)
|
||||
{
|
||||
if($this->_columnName[$col])
|
||||
{
|
||||
if($this->_columnName[$col]['Description'] != "")
|
||||
{
|
||||
return $this->_columnName[$col]['Description'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "No description available";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: string name(string $name)
|
||||
// Converts a friendly name to a MySQL column name
|
||||
function column($name)
|
||||
{
|
||||
while ($column = current($this->_columnName))
|
||||
{
|
||||
if($this->_columnName[key($this->_columnName)]['Name'] == $name)
|
||||
{
|
||||
return key($this->_columnName);
|
||||
}
|
||||
next($this->_columnName);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FUNCTION: string parse(array $arguments)
|
||||
// Converts an array of arguments into a MySQL query string
|
||||
// See documentation for search() under the API controller for more details
|
||||
function parse($arguments)
|
||||
{
|
||||
// Initialise our string
|
||||
$q = "SELECT ";
|
||||
|
||||
// Cycle through the fields, converting friendly names to MySQL column names
|
||||
if($arguments['fields'] != "") {
|
||||
$field = "";
|
||||
$fields = explode(",", $arguments['fields']);
|
||||
foreach ($fields as $f) {
|
||||
if($field != "") {
|
||||
$field .= ",";
|
||||
}
|
||||
// Add field to the query, with '++' placeholders for later translation
|
||||
$field .= "++$f++";
|
||||
}
|
||||
// Handle any DISTINCT arguments
|
||||
$field = str_replace("++distinct(", "DISTINCT(++", $field);
|
||||
$field = str_replace(")++", "++)", $field);
|
||||
// Add the MySQL column name to the query
|
||||
$q .= $field." ";
|
||||
} else {
|
||||
// If no fields are specified, display all fields
|
||||
$q .= "* ";
|
||||
}
|
||||
|
||||
// Append the table we're pulling data from
|
||||
$q .= "FROM ".$this->config->item('table_name');
|
||||
|
||||
// Parse the 'query' string, which is converted into a standard MySQL 'WHERE'
|
||||
// clause.
|
||||
// $s and $r can be refactored into single array definitions, but during
|
||||
// development it's easier to list them in this way for quick reference.
|
||||
if($arguments['query'] != "")
|
||||
{
|
||||
$q .= " WHERE ";
|
||||
$s = null;
|
||||
$r = null;
|
||||
// (and), becomes ' AND '
|
||||
$s[0] = '/(and)/';
|
||||
// (or), becomes ' OR '
|
||||
$s[1] = '/(or)/';
|
||||
// <, >, [ and ] all translated from their urlencoded forms
|
||||
$s[2] = '/%3C/';
|
||||
$s[3] = '/%3E/';
|
||||
$s[4] = '/%5B/';
|
||||
$s[5] = '/%5D/';
|
||||
// FieldName=, which becomes '++FieldName++ = '
|
||||
$s[6] = '/([a-zA-Z0-9\-\_\*\(\)\=\~]+)=/';
|
||||
// =Value, which becomes '= 'Value''
|
||||
$s[7] = '/=([a-zA-Z0-9\-\_\*\(\)\=\~]+)/';
|
||||
// now(), which becomes 'UNIX_TIMESTAMP(NOW())'
|
||||
$s[8] = '/now()/';
|
||||
// (, and ), which are translated to their non-HTML entity forms,
|
||||
// and with added padding
|
||||
$s[9] = '/(/';
|
||||
$s[10] = '/)/';
|
||||
// FieldName~, becomes '++FieldName++ LIKE~'
|
||||
$s[11] = '/([a-zA-Z0-9\-\_\*\(\)\=\~]+)~/';
|
||||
// ~Value, becomes ' 'Value''
|
||||
$s[12] = '/~([a-zA-Z0-9\-\_\*\(\)\=\~]+)/';
|
||||
// *, which becomes '%'
|
||||
$s[13] = '/\*/';
|
||||
|
||||
$r[0] = ' AND ';
|
||||
$r[1] = ' OR ';
|
||||
$r[2] = ' < ';
|
||||
$r[3] = ' > ';
|
||||
$r[4] = '[';
|
||||
$r[5] = ']';
|
||||
$r[6] = '++$1++ =';
|
||||
$r[7] = '= \'$1\'';
|
||||
$r[8] = 'UNIX_TIMESTAMP(NOW())';
|
||||
$r[9] = '( ';
|
||||
$r[10] = ' )';
|
||||
$r[11] = '++$1++ LIKE~';
|
||||
$r[12] = ' \'$1\'';
|
||||
$r[13] = '%';
|
||||
|
||||
// Bulk replace everything
|
||||
$q .= preg_replace($s, $r, $arguments['query']);
|
||||
}
|
||||
|
||||
// Parse any order arguments
|
||||
if($arguments['order'] != "")
|
||||
{
|
||||
$q .= " ORDER BY ";
|
||||
|
||||
$s = null;
|
||||
$r = null;
|
||||
$s[0] = '/(/';
|
||||
$s[1] = '/)/';
|
||||
$s[2] = '/([a-zA-Z0-9\-\_]+)([,\(]{1}|$)/';
|
||||
$s[3] = '/\(asc\)/';
|
||||
$s[4] = '/\(desc\)/';
|
||||
$s[5] = '/,$/';
|
||||
|
||||
$r[0] = '(';
|
||||
$r[1] = ')';
|
||||
$r[2] = '++$1++ $2';
|
||||
$r[3] = ' ASC ';
|
||||
$r[4] = ' DESC ';
|
||||
$r[5] = '';
|
||||
|
||||
$q .= preg_replace($s, $r, $arguments['order']);
|
||||
|
||||
}
|
||||
|
||||
// Do search/replace on field names, to convert from friendly names
|
||||
// to MySQL column names
|
||||
while (list($key, $val) = each($this->_columnName)) {
|
||||
$q = str_replace("++".$val['Name']."++", $key, $q);
|
||||
}
|
||||
|
||||
// Parse any limit arguments
|
||||
if($arguments['limit'] != "")
|
||||
{
|
||||
// Add the limit arguments, removing any characters other than numbers and commas
|
||||
$q .= " LIMIT " . preg_replace(array("/[^0-9\,]/","/,$/"), "", $arguments['limit']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no limit argument is given, default to the first 20 results
|
||||
$q .= " LIMIT 0,20";
|
||||
}
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
// ARRAY: $_columnName
|
||||
// An array matching MySQL column names to friendly names, descriptions and types
|
||||
private $_columnName = array(
|
||||
'COL_PRIMARY_KEY' => array('Name' => 'ID', 'Description' => 'Unique QSO ID', 'Type' => 'I'),
|
||||
'COL_ADDRESS' => array('Name' => 'Address', 'Description' => 'Operator\'s address', 'Type' => 'S'),
|
||||
'COL_AGE' => array('Name' => 'Age', 'Description' => 'Operator\'s age', 'Type' => 'I'),
|
||||
'COL_A_INDEX' => array('Name' => 'AIndex', 'Description' => 'Solar A Index', 'Type' => 'I'),
|
||||
'COL_ANT_AZ' => array('Name' => 'AntennaAzimuth', 'Description' => 'Antenna azimuth', 'Type' => 'I'),
|
||||
'COL_ANT_EL' => array('Name' => 'AntennaElevation', 'Description' => 'Antenna elevation', 'Type' => 'I'),
|
||||
'COL_ANT_PATH' => array('Name' => 'AntennaPath', 'Description' => 'Antenna path', 'Type' => ''),
|
||||
'COL_ARRL_SECT' => array('Name' => 'ARRLSection', 'Description' => 'ARRL Section', 'Type' => ''),
|
||||
'COL_BAND' => array('Name' => 'Band', 'Description' => 'Band', 'Type' => ''),
|
||||
'COL_BAND_RX' => array('Name' => 'BandRX', 'Description' => '', 'Type' => ''),
|
||||
'COL_BIOGRAPHY' => array('Name' => 'Biography', 'Description' => '', 'Type' => ''),
|
||||
'COL_CALL' => array('Name' => 'Call', 'Description' => '', 'Type' => ''),
|
||||
'COL_CHECK' => array('Name' => 'UNK_CHECK', 'Description' => '', 'Type' => ''),
|
||||
'COL_CLASS' => array('Name' => 'Class', 'Description' => '', 'Type' => ''),
|
||||
'COL_CNTY' => array('Name' => 'County', 'Description' => '', 'Type' => ''),
|
||||
'COL_COMMENT' => array('Name' => 'Comment', 'Description' => '', 'Type' => ''),
|
||||
'COL_CONT' => array('Name' => 'Continent', 'Description' => '', 'Type' => ''),
|
||||
'COL_CONTACTED_OP' => array('Name' => 'UNK_CONTACTED_OP', 'Description' => '', 'Type' => ''),
|
||||
'COL_CONTEST_ID' => array('Name' => 'ContestID', 'Description' => '', 'Type' => ''),
|
||||
'COL_COUNTRY' => array('Name' => 'Country', 'Description' => '', 'Type' => ''),
|
||||
'COL_CQZ' => array('Name' => 'CQZone', 'Description' => '', 'Type' => ''),
|
||||
'COL_DISTANCE' => array('Name' => 'Distance', 'Description' => '', 'Type' => ''),
|
||||
'COL_DXCC' => array('Name' => 'DXCC', 'Description' => '', 'Type' => ''),
|
||||
'COL_EMAIL' => array('Name' => 'EMail', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQ_CALL' => array('Name' => 'UNK_EQ_CALL', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQSL_QSLRDATE' => array('Name' => 'EQSLRecievedDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQSL_QSLSDATE' => array('Name' => 'EQSLSentDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQSL_QSL_RCVD' => array('Name' => 'EQSLRecieved', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQSL_QSL_SENT' => array('Name' => 'EQSLSent', 'Description' => '', 'Type' => ''),
|
||||
'COL_EQSL_STATUS' => array('Name' => 'EQSLStatus', 'Description' => '', 'Type' => ''),
|
||||
'COL_FORCE_INIT' => array('Name' => 'UNK_FORCE_INIT', 'Description' => '', 'Type' => ''),
|
||||
'COL_FREQ' => array('Name' => 'Frequency', 'Description' => '', 'Type' => ''),
|
||||
'COL_FREQ_RX' => array('Name' => 'FrequencyRX', 'Description' => '', 'Type' => ''),
|
||||
'COL_GRIDSQUARE' => array('Name' => 'Locator', 'Description' => '', 'Type' => ''),
|
||||
'COL_HEADING' => array('Name' => 'Heading', 'Description' => '', 'Type' => ''),
|
||||
'COL_IOTA' => array('Name' => 'IOTA', 'Description' => '', 'Type' => ''),
|
||||
'COL_ITUZ' => array('Name' => 'ITUZone', 'Description' => '', 'Type' => ''),
|
||||
'COL_K_INDEX' => array('Name' => 'KIndex', 'Description' => '', 'Type' => ''),
|
||||
'COL_LAT' => array('Name' => 'Latitude', 'Description' => '', 'Type' => ''),
|
||||
'COL_LON' => array('Name' => 'Longitude', 'Description' => '', 'Type' => ''),
|
||||
'COL_LOTW_QSLRDATE' => array('Name' => 'LOTWRecievedDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_LOTW_QSLSDATE' => array('Name' => 'LOTWSentDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_LOTW_QSL_RCVD' => array('Name' => 'LOTWRecieved', 'Description' => '', 'Type' => ''),
|
||||
'COL_LOTW_QSL_SENT' => array('Name' => 'LOTWSent', 'Description' => '', 'Type' => ''),
|
||||
'COL_LOTW_STATUS' => array('Name' => 'LOTWStatus', 'Description' => '', 'Type' => ''),
|
||||
'COL_MAX_BURSTS' => array('Name' => 'MaxBursts', 'Description' => '', 'Type' => ''),
|
||||
'COL_MODE' => array('Name' => 'Mode', 'Description' => '', 'Type' => ''),
|
||||
'COL_MS_SHOWER' => array('Name' => 'MSShower', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_CITY' => array('Name' => 'MyCity', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_CNTY' => array('Name' => 'MyCounty', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_COUNTRY' => array('Name' => 'MyCountry', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_CQ_ZONE' => array('Name' => 'MyCQZone', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_GRIDSQUARE' => array('Name' => 'MyLocator', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_IOTA' => array('Name' => 'MyIOTA', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_ITU_ZONE' => array('Name' => 'MyITUZone', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_LAT' => array('Name' => 'MyLatitude', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_LON' => array('Name' => 'MyLongitude', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_NAME' => array('Name' => 'MyName', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_POSTAL_CODE' => array('Name' => 'MyPostalCode', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_RIG' => array('Name' => 'MyRig', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_SIG' => array('Name' => 'MySig', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_SIG_INFO' => array('Name' => 'MySigInfo', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_STATE' => array('Name' => 'MyState', 'Description' => '', 'Type' => ''),
|
||||
'COL_MY_STREET' => array('Name' => 'MyStreet', 'Description' => '', 'Type' => ''),
|
||||
'COL_NAME' => array('Name' => 'Name', 'Description' => '', 'Type' => ''),
|
||||
'COL_NOTES' => array('Name' => 'Notes', 'Description' => '', 'Type' => ''),
|
||||
'COL_NR_BURSTS' => array('Name' => 'NumBursts', 'Description' => '', 'Type' => ''),
|
||||
'COL_NR_PINGS' => array('Name' => 'NumPings', 'Description' => '', 'Type' => ''),
|
||||
'COL_OPERATOR' => array('Name' => 'Operator', 'Description' => '', 'Type' => ''),
|
||||
'COL_OWNER_CALLSIGN' => array('Name' => 'OwnerCallsign', 'Description' => '', 'Type' => ''),
|
||||
'COL_PFX' => array('Name' => 'Prefix', 'Description' => '', 'Type' => ''),
|
||||
'COL_PRECEDENCE' => array('Name' => 'Precedence', 'Description' => '', 'Type' => ''),
|
||||
'COL_PROP_MODE' => array('Name' => 'PropMode', 'Description' => '', 'Type' => ''),
|
||||
'COL_PUBLIC_KEY' => array('Name' => 'PublicKey', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSLMSG' => array('Name' => 'QSLMessage', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSLRDATE' => array('Name' => 'QSLRecievedDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSLSDATE' => array('Name' => 'QSLSentDate', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSL_RCVD' => array('Name' => 'QSLRecieved', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSL_RCVD_VIA' => array('Name' => 'QSLRecievedVia', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSL_SENT' => array('Name' => 'QSLSent', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSL_SENT_VIA' => array('Name' => 'QSLSentVia', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSL_VIA' => array('Name' => 'QSLVia', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSO_COMPLETE' => array('Name' => 'QSOComplete', 'Description' => '', 'Type' => ''),
|
||||
'COL_QSO_RANDOM' => array('Name' => 'QSORandom', 'Description' => '', 'Type' => ''),
|
||||
'COL_QTH' => array('Name' => 'QTH', 'Description' => '', 'Type' => ''),
|
||||
'COL_RIG' => array('Name' => 'Rig', 'Description' => '', 'Type' => ''),
|
||||
'COL_RST_RCVD' => array('Name' => 'ReportRecieved', 'Description' => '', 'Type' => ''),
|
||||
'COL_RST_SENT' => array('Name' => 'ReportSent', 'Description' => '', 'Type' => ''),
|
||||
'COL_RX_PWR' => array('Name' => 'RXPower', 'Description' => '', 'Type' => ''),
|
||||
'COL_SAT_MODE' => array('Name' => 'SatMode', 'Description' => '', 'Type' => ''),
|
||||
'COL_SAT_NAME' => array('Name' => 'SatName', 'Description' => '', 'Type' => ''),
|
||||
'COL_SFI' => array('Name' => 'SFI', 'Description' => '', 'Type' => ''),
|
||||
'COL_SIG' => array('Name' => 'Sig', 'Description' => '', 'Type' => ''),
|
||||
'COL_SIG_INFO' => array('Name' => 'SigInfo', 'Description' => '', 'Type' => ''),
|
||||
'COL_SRX' => array('Name' => 'UNK_SRX', 'Description' => '', 'Type' => ''),
|
||||
'COL_STX' => array('Name' => 'UNK_STX', 'Description' => '', 'Type' => ''),
|
||||
'COL_SRX_STRING' => array('Name' => 'UNK_SRX_STRING', 'Description' => '', 'Type' => ''),
|
||||
'COL_STX_STRING' => array('Name' => 'UNK_STX_STRING', 'Description' => '', 'Type' => ''),
|
||||
'COL_STATE' => array('Name' => 'State', 'Description' => '', 'Type' => ''),
|
||||
'COL_STATION_CALLSIGN' => array('Name' => 'StationCall', 'Description' => '', 'Type' => ''),
|
||||
'COL_SWL' => array('Name' => 'SWL', 'Description' => '', 'Type' => ''),
|
||||
'COL_TEN_TEN' => array('Name' => 'TenTen', 'Description' => '', 'Type' => ''),
|
||||
'COL_TIME_OFF' => array('Name' => 'TimeOff', 'Description' => '', 'Type' => ''),
|
||||
'COL_TIME_ON' => array('Name' => 'TimeOn', 'Description' => '', 'Type' => ''),
|
||||
'COL_TX_PWR' => array('Name' => 'TXPower', 'Description' => '', 'Type' => ''),
|
||||
'COL_WEB' => array('Name' => 'Website', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_0' => array('Name' => 'UNK_USER_DEFINED_0', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_1' => array('Name' => 'UNK_USER_DEFINED_1', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_2' => array('Name' => 'UNK_USER_DEFINED_2', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_3' => array('Name' => 'UNK_USER_DEFINED_3', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_4' => array('Name' => 'UNK_USER_DEFINED_4', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_5' => array('Name' => 'UNK_USER_DEFINED_5', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_6' => array('Name' => 'UNK_USER_DEFINED_6', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_7' => array('Name' => 'UNK_USER_DEFINED_7', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_8' => array('Name' => 'UNK_USER_DEFINED_8', 'Description' => '', 'Type' => ''),
|
||||
'COL_USER_DEFINED_9' => array('Name' => 'UNK_USER_DEFINED_9', 'Description' => '', 'Type' => ''),
|
||||
'COL_CREDIT_GRANTED' => array('Name' => 'UNK_CREDIT_GRANTED', 'Description' => '', 'Type' => ''),
|
||||
'COL_CREDIT_SUBMITTED' => array('Name' => 'UNK_CREDIT_SUBMITTED', 'Description' => '', 'Type' => ''),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
// Uses 'phpass' from http://www.openwall.com/phpass/ to implement password hashing
|
||||
require_once('application/third_party/PasswordHash.php');
|
||||
|
||||
class Auth_Model extends CI_Model {
|
||||
|
||||
function __construct()
|
||||
{
|
||||
// Call the Model constructor
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
// Test function, can be removed once class is complete
|
||||
function test() {
|
||||
$hash = $this->_hash("password");
|
||||
echo "Password hashed is '".$hash."\n";
|
||||
echo "Does 'password' match '$hash'? result is ".$this->_auth("password", $hash)."\n";
|
||||
|
||||
}
|
||||
|
||||
// Retrieve a user
|
||||
function get($username) {
|
||||
$this->db->where('user_name', $username);
|
||||
$r = $this->db->get($this->config->item('auth_table'));
|
||||
if($r->num_rows == 1) {
|
||||
return $r->result();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function exists($username) {
|
||||
if($this->get($username)->num_rows == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function add($username, $password, $email, $type) {
|
||||
if(!$this->exists($username)) {
|
||||
$data = array(
|
||||
'user_name' => $username,
|
||||
'user_password' => $this->_hash($password),
|
||||
'user_email' => $email,
|
||||
'user_type' => $type
|
||||
);
|
||||
|
||||
$this->db->insert($this->config->item('auth_table'));
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function authenticate($username, $password) {
|
||||
$u = $this->get($username);
|
||||
if($this->_hash($password, $u['user_password'])) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function set($username, $data) {
|
||||
$this->db->where('user_name', $username);
|
||||
$this->db->update($this->config->item('auth_table', $data));
|
||||
return 1;
|
||||
}
|
||||
|
||||
private function _auth($password, $hash) {
|
||||
$h = new PasswordHash(8, FALSE);
|
||||
if($h->CheckPassword($password, $hash)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private function _hash($password) {
|
||||
$h = new PasswordHash(8, FALSE);
|
||||
$hash = $h->HashPassword($password);
|
||||
unset($h);
|
||||
|
||||
if(strlen($hash) < 20) {
|
||||
return 0;
|
||||
} else {
|
||||
return $hash;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
253
application/third_party/PasswordHash.php
vendored
普通文件
253
application/third_party/PasswordHash.php
vendored
普通文件
|
|
@ -0,0 +1,253 @@
|
|||
<?php
|
||||
#
|
||||
# Portable PHP password hashing framework.
|
||||
#
|
||||
# Version 0.3 / genuine.
|
||||
#
|
||||
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
|
||||
# the public domain. Revised in subsequent years, still public domain.
|
||||
#
|
||||
# There's absolutely no warranty.
|
||||
#
|
||||
# The homepage URL for this framework is:
|
||||
#
|
||||
# http://www.openwall.com/phpass/
|
||||
#
|
||||
# Please be sure to update the Version line if you edit this file in any way.
|
||||
# It is suggested that you leave the main version number intact, but indicate
|
||||
# your project name (after the slash) and add your own revision information.
|
||||
#
|
||||
# Please do not change the "private" password hashing method implemented in
|
||||
# here, thereby making your hashes incompatible. However, if you must, please
|
||||
# change the hash type identifier (the "$P$") to something different.
|
||||
#
|
||||
# Obviously, since this code is in the public domain, the above are not
|
||||
# requirements (there can be none), but merely suggestions.
|
||||
#
|
||||
class PasswordHash {
|
||||
var $itoa64;
|
||||
var $iteration_count_log2;
|
||||
var $portable_hashes;
|
||||
var $random_state;
|
||||
|
||||
function PasswordHash($iteration_count_log2, $portable_hashes)
|
||||
{
|
||||
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
|
||||
$iteration_count_log2 = 8;
|
||||
$this->iteration_count_log2 = $iteration_count_log2;
|
||||
|
||||
$this->portable_hashes = $portable_hashes;
|
||||
|
||||
$this->random_state = microtime();
|
||||
if (function_exists('getmypid'))
|
||||
$this->random_state .= getmypid();
|
||||
}
|
||||
|
||||
function get_random_bytes($count)
|
||||
{
|
||||
$output = '';
|
||||
if (is_readable('/dev/urandom') &&
|
||||
($fh = @fopen('/dev/urandom', 'rb'))) {
|
||||
$output = fread($fh, $count);
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
if (strlen($output) < $count) {
|
||||
$output = '';
|
||||
for ($i = 0; $i < $count; $i += 16) {
|
||||
$this->random_state =
|
||||
md5(microtime() . $this->random_state);
|
||||
$output .=
|
||||
pack('H*', md5($this->random_state));
|
||||
}
|
||||
$output = substr($output, 0, $count);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function encode64($input, $count)
|
||||
{
|
||||
$output = '';
|
||||
$i = 0;
|
||||
do {
|
||||
$value = ord($input[$i++]);
|
||||
$output .= $this->itoa64[$value & 0x3f];
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 8;
|
||||
$output .= $this->itoa64[($value >> 6) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 16;
|
||||
$output .= $this->itoa64[($value >> 12) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
$output .= $this->itoa64[($value >> 18) & 0x3f];
|
||||
} while ($i < $count);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_private($input)
|
||||
{
|
||||
$output = '$P$';
|
||||
$output .= $this->itoa64[min($this->iteration_count_log2 +
|
||||
((PHP_VERSION >= '5') ? 5 : 3), 30)];
|
||||
$output .= $this->encode64($input, 6);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function crypt_private($password, $setting)
|
||||
{
|
||||
$output = '*0';
|
||||
if (substr($setting, 0, 2) == $output)
|
||||
$output = '*1';
|
||||
|
||||
$id = substr($setting, 0, 3);
|
||||
# We use "$P$", phpBB3 uses "$H$" for the same thing
|
||||
if ($id != '$P$' && $id != '$H$')
|
||||
return $output;
|
||||
|
||||
$count_log2 = strpos($this->itoa64, $setting[3]);
|
||||
if ($count_log2 < 7 || $count_log2 > 30)
|
||||
return $output;
|
||||
|
||||
$count = 1 << $count_log2;
|
||||
|
||||
$salt = substr($setting, 4, 8);
|
||||
if (strlen($salt) != 8)
|
||||
return $output;
|
||||
|
||||
# We're kind of forced to use MD5 here since it's the only
|
||||
# cryptographic primitive available in all versions of PHP
|
||||
# currently in use. To implement our own low-level crypto
|
||||
# in PHP would result in much worse performance and
|
||||
# consequently in lower iteration counts and hashes that are
|
||||
# quicker to crack (by non-PHP code).
|
||||
if (PHP_VERSION >= '5') {
|
||||
$hash = md5($salt . $password, TRUE);
|
||||
do {
|
||||
$hash = md5($hash . $password, TRUE);
|
||||
} while (--$count);
|
||||
} else {
|
||||
$hash = pack('H*', md5($salt . $password));
|
||||
do {
|
||||
$hash = pack('H*', md5($hash . $password));
|
||||
} while (--$count);
|
||||
}
|
||||
|
||||
$output = substr($setting, 0, 12);
|
||||
$output .= $this->encode64($hash, 16);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_extended($input)
|
||||
{
|
||||
$count_log2 = min($this->iteration_count_log2 + 8, 24);
|
||||
# This should be odd to not reveal weak DES keys, and the
|
||||
# maximum valid value is (2**24 - 1) which is odd anyway.
|
||||
$count = (1 << $count_log2) - 1;
|
||||
|
||||
$output = '_';
|
||||
$output .= $this->itoa64[$count & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 6) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 12) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 18) & 0x3f];
|
||||
|
||||
$output .= $this->encode64($input, 3);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_blowfish($input)
|
||||
{
|
||||
# This one needs to use a different order of characters and a
|
||||
# different encoding scheme from the one in encode64() above.
|
||||
# We care because the last character in our encoded string will
|
||||
# only represent 2 bits. While two known implementations of
|
||||
# bcrypt will happily accept and correct a salt string which
|
||||
# has the 4 unused bits set to non-zero, we do not want to take
|
||||
# chances and we also do not want to waste an additional byte
|
||||
# of entropy.
|
||||
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
$output = '$2a$';
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
|
||||
$output .= '$';
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
$c1 = ord($input[$i++]);
|
||||
$output .= $itoa64[$c1 >> 2];
|
||||
$c1 = ($c1 & 0x03) << 4;
|
||||
if ($i >= 16) {
|
||||
$output .= $itoa64[$c1];
|
||||
break;
|
||||
}
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 4;
|
||||
$output .= $itoa64[$c1];
|
||||
$c1 = ($c2 & 0x0f) << 2;
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 6;
|
||||
$output .= $itoa64[$c1];
|
||||
$output .= $itoa64[$c2 & 0x3f];
|
||||
} while (1);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function HashPassword($password)
|
||||
{
|
||||
$random = '';
|
||||
|
||||
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
|
||||
$random = $this->get_random_bytes(16);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_blowfish($random));
|
||||
if (strlen($hash) == 60)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
|
||||
if (strlen($random) < 3)
|
||||
$random = $this->get_random_bytes(3);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_extended($random));
|
||||
if (strlen($hash) == 20)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (strlen($random) < 6)
|
||||
$random = $this->get_random_bytes(6);
|
||||
$hash =
|
||||
$this->crypt_private($password,
|
||||
$this->gensalt_private($random));
|
||||
if (strlen($hash) == 34)
|
||||
return $hash;
|
||||
|
||||
# Returning '*' on error is safe here, but would _not_ be safe
|
||||
# in a crypt(3)-like function used _both_ for generating new
|
||||
# hashes and for validating passwords against existing hashes.
|
||||
return '*';
|
||||
}
|
||||
|
||||
function CheckPassword($password, $stored_hash)
|
||||
{
|
||||
$hash = $this->crypt_private($password, $stored_hash);
|
||||
if ($hash[0] == '*')
|
||||
$hash = crypt($password, $stored_hash);
|
||||
|
||||
return $hash == $stored_hash;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
117
application/views/api/index.php
普通文件
117
application/views/api/index.php
普通文件
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
// Set the content-type for browsers
|
||||
header("Content-type: text/xml");
|
||||
|
||||
// Create the DOMDocument for the XML output
|
||||
$xmlDoc = new DOMDocument("1.0");
|
||||
// Add reference to the XSLT
|
||||
$xsl = $xmlDoc->createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"/css/api.xsl\"");
|
||||
$xmlDoc->appendChild($xsl);
|
||||
|
||||
// Get the method called, and build the root node
|
||||
$call = $data['queryInfo']['call'];
|
||||
$rootNode = $xmlDoc->createElement("HRDWebLogbook-API");
|
||||
$parentNode = $xmlDoc->appendChild($rootNode);
|
||||
|
||||
// Get the results output
|
||||
$output = $data[$call."_Result"];
|
||||
|
||||
// Add the queryInfo node
|
||||
$node = $xmlDoc->createElement("queryInfo");
|
||||
$queryElement = $parentNode->appendChild($node);
|
||||
$queryElement->setAttribute("timeStamp", date("r", time()));
|
||||
$queryElement->setAttribute("calledMethod", $data['queryInfo']['call']);
|
||||
//$queryElement->setAttribute("queryArgs", $queryArgsString);
|
||||
$queryElement->setAttribute("resultsCount", count($data['queryInfo']['numResults']));
|
||||
if(ENVIRONMENT == "development") {
|
||||
$debugInfo = $xmlDoc->createElement("debugInfo");
|
||||
$debugElement = $queryElement->appendChild($debugInfo);
|
||||
$debugElement->setAttribute("dbQuery", $data['queryInfo']['dbQuery']);
|
||||
$debugElement->setAttribute("clientVersion", $_SERVER['HTTP_USER_AGENT']);
|
||||
$debugElement->setAttribute("requestURI", $_SERVER['REQUEST_URI']);
|
||||
$debugElement->setAttribute("benchMark", $this->benchmark->marker['total_execution_time_start'].", ".$this->benchmark->marker['loading_time:_base_classes_start'].", ".$this->benchmark->marker['loading_time:_base_classes_end'].", ".$this->benchmark->marker['controller_execution_time_( api / search )_start']);
|
||||
}
|
||||
$queryElement->setAttribute("executionTime", $data['queryInfo']['executionTime']);
|
||||
$queryElement->setAttribute("logbookURL", $this->config->item('base_url'));
|
||||
|
||||
// Add the main results node
|
||||
$node = $xmlDoc->createElement("elements");
|
||||
$elementsNode = $parentNode->appendChild($node);
|
||||
|
||||
// Cycle through the results and add to the results node
|
||||
if($output['results'])
|
||||
{
|
||||
foreach($output['results'] as $e) {
|
||||
$node = $xmlDoc->createElement("element");
|
||||
$element = $elementsNode->appendChild($node);
|
||||
|
||||
foreach($e as $attr) {
|
||||
#while($attr = current($e)) {
|
||||
if(is_array($attr))
|
||||
{
|
||||
foreach($attr as $subattr)
|
||||
{
|
||||
$node = $xmlDoc->createElement(key($e));
|
||||
foreach($subattr as $subsubattr)
|
||||
{
|
||||
$node->setAttribute(key($subattr), $subsubattr);
|
||||
next($subattr);
|
||||
}
|
||||
$element->appendChild($node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$element->setAttribute(key($e), $attr);
|
||||
}
|
||||
next($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output formatted XML
|
||||
echo formatXmlString($xmlDoc->saveXML());
|
||||
|
||||
// This function tidies up the outputted XML
|
||||
function formatXmlString($xml) {
|
||||
|
||||
// add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
|
||||
$xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $xml);
|
||||
|
||||
// now indent the tags
|
||||
$token = strtok($xml, "\n");
|
||||
$result = ''; // holds formatted version as it is built
|
||||
$pad = 0; // initial indent
|
||||
$matches = array(); // returns from preg_matches()
|
||||
|
||||
// scan each line and adjust indent based on opening/closing tags
|
||||
while ($token !== false) :
|
||||
|
||||
// test for the various tag states
|
||||
|
||||
// 1. open and closing tags on same line - no change
|
||||
if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) :
|
||||
$indent=0;
|
||||
// 2. closing tag - outdent now
|
||||
elseif (preg_match('/^<\/\w/', $token, $matches)) :
|
||||
$pad--;
|
||||
// 3. opening tag - don't pad this one, only subsequent tags
|
||||
elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) :
|
||||
$indent=1;
|
||||
// 4. no indentation needed
|
||||
else :
|
||||
$indent = 0;
|
||||
endif;
|
||||
|
||||
// pad the line with the required number of leading spaces
|
||||
$line = str_pad($token, strlen($token)+$pad, ' ', STR_PAD_LEFT);
|
||||
$result .= $line . "\n"; // add to the cumulative result, with linefeed
|
||||
$token = strtok("\n"); // get the next token
|
||||
$pad += $indent; // update the pad size for subsequent lines
|
||||
endwhile;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
?>
|
||||
70
application/views/auth/add.php
普通文件
70
application/views/auth/add.php
普通文件
|
|
@ -0,0 +1,70 @@
|
|||
<h2>Add Note</h2>
|
||||
<div class="wrap_content">
|
||||
<?php echo validation_errors(); ?>
|
||||
<form method="post" action="<?php echo site_url('notes/add'); ?>" name="notes_add" id="notes_add">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="title">Title</label></td>
|
||||
<td><input type="text" name="title" value="" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><label for="category">Category</label></td>
|
||||
<td><select name="category">
|
||||
<option value="General" selected="selected">General</option>
|
||||
<option value="Antennas">Antennas</option>
|
||||
<option value="Satellites">Satellites</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><textarea name="content" id="markItUp" rows="10" cols="10"></textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div><input type="submit" value="Submit" /></div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
// Add markItUp! to your textarea in one line
|
||||
// $('textarea').markItUp( { Settings }, { OptionalExtraSettings } );
|
||||
$('#markItUp').markItUp(mySettings);
|
||||
|
||||
// You can add content from anywhere in your page
|
||||
// $.markItUp( { Settings } );
|
||||
$('.add').click(function() {
|
||||
$.markItUp( { openWith:'<opening tag>',
|
||||
closeWith:'<\/closing tag>',
|
||||
placeHolder:"New content"
|
||||
}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
// And you can add/remove markItUp! whenever you want
|
||||
// $(textarea).markItUpRemove();
|
||||
$('.toggle').click(function() {
|
||||
if ($("#markItUp.markItUpEditor").length === 1) {
|
||||
$("#markItUp").markItUpRemove();
|
||||
$("span", this).text("get markItUp! back");
|
||||
} else {
|
||||
$('#markItUp').markItUp(mySettings);
|
||||
$("span", this).text("remove markItUp!");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>markitup/jquery.markitup.js"></script>
|
||||
<!-- markItUp! toolbar settings -->
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>markitup/sets/html/set.js"></script>
|
||||
<!-- markItUp! skin -->
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/skins/markitup/style.css" />
|
||||
<!-- markItUp! toolbar skin -->
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/sets/html/style.css" />
|
||||
72
application/views/auth/edit.php
普通文件
72
application/views/auth/edit.php
普通文件
|
|
@ -0,0 +1,72 @@
|
|||
<?php foreach ($note->result() as $row) { ?>
|
||||
<h2>Edit Note - <?php echo $row->title; ?></h2>
|
||||
<div class="wrap_content">
|
||||
<?php echo validation_errors(); ?>
|
||||
<form method="post" action="<?php echo site_url('notes/edit'); ?>/<?php echo $id; ?>" name="notes_add" id="notes_add">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="title">Title</label></td>
|
||||
<td><input type="text" name="title" value="<?php echo $row->title; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><label for="category">Category</label></td>
|
||||
<td><select name="category">
|
||||
<option value="General" selected="selected">General</option>
|
||||
<option value="Antennas">Antennas</option>
|
||||
<option value="Satellites">Satellites</option>
|
||||
</select></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><input type="hidden" name="id" value="<?php echo $id; ?>" /></td>
|
||||
<td><textarea name="content" id="markItUp" rows="10" cols="10"><?php echo $row->note; ?></textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div><input type="submit" value="Submit" /></div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<?php } ?>
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
// Add markItUp! to your textarea in one line
|
||||
// $('textarea').markItUp( { Settings }, { OptionalExtraSettings } );
|
||||
$('#markItUp').markItUp(mySettings);
|
||||
|
||||
// You can add content from anywhere in your page
|
||||
// $.markItUp( { Settings } );
|
||||
$('.add').click(function() {
|
||||
$.markItUp( { openWith:'<opening tag>',
|
||||
closeWith:'<\/closing tag>',
|
||||
placeHolder:"New content"
|
||||
}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
// And you can add/remove markItUp! whenever you want
|
||||
// $(textarea).markItUpRemove();
|
||||
$('.toggle').click(function() {
|
||||
if ($("#markItUp.markItUpEditor").length === 1) {
|
||||
$("#markItUp").markItUpRemove();
|
||||
$("span", this).text("get markItUp! back");
|
||||
} else {
|
||||
$('#markItUp').markItUp(mySettings);
|
||||
$("span", this).text("remove markItUp!");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>markitup/jquery.markitup.js"></script>
|
||||
<!-- markItUp! toolbar settings -->
|
||||
<script type="text/javascript" src="<?php echo base_url(); ?>markitup/sets/html/set.js"></script>
|
||||
<!-- markItUp! skin -->
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/skins/markitup/style.css" />
|
||||
<!-- markItUp! toolbar skin -->
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>markitup/sets/html/style.css" />
|
||||
24
application/views/auth/main.php
普通文件
24
application/views/auth/main.php
普通文件
|
|
@ -0,0 +1,24 @@
|
|||
<h2>Note</h2>
|
||||
<div class="wrap_content note">
|
||||
|
||||
<?php
|
||||
|
||||
if ($notes->num_rows() > 0)
|
||||
{
|
||||
echo "<ul class=\"notes_list\">";
|
||||
foreach ($notes->result() as $row)
|
||||
{
|
||||
echo "<li>";
|
||||
echo "<a href=\"".site_url()."/notes/view/".$row->id."\">".$row->title."</a>";
|
||||
echo "</li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
} else {
|
||||
echo "<p>You have no notes, why not create one!</p>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<p><a href="<?php echo site_url('notes/add'); ?>" title="Add Note">Create a Note</a></p>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php foreach ($note->result() as $row) { ?>
|
||||
<h2>Note - <?php echo $row->title; ?></h2>
|
||||
<div class="wrap_content note">
|
||||
<?php echo nl2br($row->note); ?>
|
||||
|
||||
<p>Options: <a href="<?php echo site_url('notes/edit'); ?>/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/application_edit.png" width="16" height="16" alt="Edit" /></a> <a href="<?php echo site_url('notes/delete'); ?>/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/delete.png" width="16" height="16" alt="Delete" /></a></p>
|
||||
</div>
|
||||
<?php } ?>
|
||||
52
css/api.css
普通文件
52
css/api.css
普通文件
|
|
@ -0,0 +1,52 @@
|
|||
body {
|
||||
background: #eee;
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 8px;
|
||||
}
|
||||
#results table {
|
||||
border: 0px solid #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#results th {
|
||||
padding: 4px;
|
||||
border: 1px solid #000;
|
||||
background-color: #6AA57B;
|
||||
font-size: 11px;
|
||||
}
|
||||
#results td {
|
||||
padding: 4px;
|
||||
border: 1px solid #000;
|
||||
font-size: 11px;
|
||||
}
|
||||
#results tr.row0 {
|
||||
background-color: #A3BDF5;
|
||||
}
|
||||
#results tr.row1 {
|
||||
background-color: #9ADF9A;
|
||||
}
|
||||
img {
|
||||
border: 0px;
|
||||
}
|
||||
#footer {
|
||||
font-size: 8px;
|
||||
}
|
||||
#debug {
|
||||
border: 1px dotted #fff;
|
||||
background-color: #c00;
|
||||
color: #fff;
|
||||
font-size: 8px;
|
||||
}
|
||||
#debug td {
|
||||
padding: 4px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
}
|
||||
.blank {
|
||||
background-color: transparent;
|
||||
}
|
||||
.sub {
|
||||
background-color: #cfc;
|
||||
}
|
||||
.subattr {
|
||||
background-color: #cfc;
|
||||
}
|
||||
66
css/api.xsl
普通文件
66
css/api.xsl
普通文件
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<head>
|
||||
<title><xsl:value-of select="//queryInfo/@calledMethod"/></title>
|
||||
<link rel="stylesheet" href="/css/api.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Output of '<xsl:value-of select="//queryInfo/@calledMethod"/>'</h1>
|
||||
<table id="results">
|
||||
<tr>
|
||||
<xsl:for-each select="//elements/element[1]/@*">
|
||||
<th><b><xsl:value-of select="name()"/></b></th>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
<xsl:for-each select="//elements/element">
|
||||
<tr class="row{position() mod 2}">
|
||||
<xsl:for-each select="@*">
|
||||
<td><xsl:value-of select="."/></td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
<xsl:for-each select="*">
|
||||
<tr>
|
||||
<td class="blank"></td>
|
||||
<td class="sub"><xsl:value-of select="name()"/></td>
|
||||
<td class="blank" colspan="20">
|
||||
<table>
|
||||
<tr>
|
||||
<xsl:for-each select="@*">
|
||||
<td class="subattr">
|
||||
<xsl:value-of select="name()"/> = <xsl:value-of select="."/>
|
||||
</td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
<p/>
|
||||
<xsl:if test="//debugInfo">
|
||||
<div id="debug">
|
||||
<table>
|
||||
<tr>
|
||||
<td><b>requestURI</b></td><td><xsl:value-of select="//debugInfo/@requestURI" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>dbQuery</b></td><td><xsl:value-of select="//debugInfo/@dbQuery" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>clientVersion</b></td><td><xsl:value-of select="//debugInfo/@clientVersion" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p/>
|
||||
</xsl:if>
|
||||
<div id="footer">
|
||||
Retrieved from the <xsl:element name="a"><xsl:attribute name="href"><xsl:value-of select="//queryInfo/logbookURL"/>/index.php/api</xsl:attribute>HRD Web Frontend</xsl:element> API at <b><xsl:value-of select="//queryInfo/@timeStamp"/></b>. Query took <b><xsl:value-of select="//queryInfo/@executionTime"/></b> seconds.<br/>This is formatted XML using XSLT.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
正在加载…
在新工单中引用