Initial g3 remote client implementation
320
web_client/@install.php
Normal file
@ -0,0 +1,320 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed. This file is automatically ran by index.php.'); ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<title>Kohana Installation</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
width: 42em;
|
||||
margin: 0 auto;
|
||||
font-family: sans-serif;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
#tests table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#tests table th, #tests table td {
|
||||
padding: 0.2em 0.4em;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#tests table th {
|
||||
width: 12em;
|
||||
font-weight: normal;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#tests table tr:nth-child(odd) {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
#tests table td.pass {
|
||||
color: #191;
|
||||
}
|
||||
|
||||
#tests table td.fail {
|
||||
color: #911;
|
||||
}
|
||||
|
||||
#tests #results {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#tests #results p {
|
||||
padding: 0.8em 0.4em;
|
||||
}
|
||||
|
||||
#tests #results p.pass {
|
||||
background: #191;
|
||||
}
|
||||
|
||||
#tests #results p.fail {
|
||||
background: #911;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Environment Tests</h1>
|
||||
<p>
|
||||
The following tests have been run to determine if Kohana will work in your environment. If any of the tests have failed, consult the <a href="http://docs.kohanaphp.com/installation">documentation</a>
|
||||
for more information on how to correct the problem.
|
||||
</p>
|
||||
<div id="tests">
|
||||
<?php $failed = FALSE?>
|
||||
<table cellspacing="0">
|
||||
<tr>
|
||||
<th>PHP Version</th>
|
||||
<?php if (version_compare(PHP_VERSION, '5.2', '>=')): ?>
|
||||
<td class="pass">
|
||||
<?php echo PHP_VERSION?>
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
Kohana requires PHP 5.2 or newer, this version is <?php echo PHP_VERSION?>.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>System Directory</th>
|
||||
<?php if (is_dir(SYSPATH)): ?>
|
||||
<td class="pass">
|
||||
<?php echo SYSPATH?>
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The configured
|
||||
<code>
|
||||
system
|
||||
</code>
|
||||
directory does not exist or does not contain required files.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Application Directory</th>
|
||||
<?php if (is_dir(APPPATH) AND is_file(APPPATH.'config/config'.EXT) AND is_file(APPPATH.'Bootstrap'.EXT)): ?>
|
||||
<td class="pass">
|
||||
<?php echo APPPATH?>
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The configured
|
||||
<code>
|
||||
application
|
||||
</code>
|
||||
directory does not exist or does not contain required files.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Modules Directory</th>
|
||||
<?php if (is_dir(MODPATH)): ?>
|
||||
<td class="pass">
|
||||
<?php echo MODPATH?>
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The configured
|
||||
<code>
|
||||
modules
|
||||
</code>
|
||||
directory does not exist or does not contain required files.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Logs Directory</th>
|
||||
<?php if (is_dir(APPPATH.'logs') AND is_writable(APPPATH.'logs')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The default
|
||||
<code>
|
||||
logs
|
||||
</code>
|
||||
directory does not exist or is not writable. Depending on your log driver and config settings, this may not be a problem.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cache Directory</th>
|
||||
<?php if (is_dir(APPPATH.'cache') AND is_writable(APPPATH.'cache')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The default
|
||||
<code>
|
||||
cache
|
||||
</code>
|
||||
directory does not exist or is not writable. Depending on your cache driver and config settings, this may not be a problem.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>PCRE UTF-8</th>
|
||||
<?php if ( ! function_exists('preg_match')): $failed = TRUE?>
|
||||
<td class="fail">
|
||||
<a href="http://php.net/pcre">PCRE</a>
|
||||
support is missing.
|
||||
</td>
|
||||
<?php elseif ( ! @preg_match('/^.$/u', 'ñ')): $failed = TRUE?>
|
||||
<td class="fail">
|
||||
<a href="http://php.net/pcre">PCRE</a>
|
||||
has not been compiled with UTF-8 support.
|
||||
</td>
|
||||
<?php elseif ( ! @preg_match('/^\pL$/u', 'ñ')): $failed = TRUE?>
|
||||
<td class="fail">
|
||||
<a href="http://php.net/pcre">PCRE</a>
|
||||
has not been compiled with Unicode property support.
|
||||
</td>
|
||||
<?php else : ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Reflection Enabled</th>
|
||||
<?php if (class_exists('ReflectionClass')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
PHP <a href="http://www.php.net/reflection">reflection</a>
|
||||
is either not loaded or not compiled in.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Filters Enabled</th>
|
||||
<?php if (function_exists('filter_list')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The <a href="http://www.php.net/filter">filter</a>
|
||||
extension is either not loaded or not compiled in.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Iconv Extension Loaded</th>
|
||||
<?php if (extension_loaded('iconv')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The <a href="http://php.net/iconv">iconv</a>
|
||||
extension is not loaded.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>SPL Enabled</th>
|
||||
<?php if (function_exists('spl_autoload_register')): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
<a href="http://php.net/spl">SPL</a>
|
||||
is not enabled.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Multibyte String Enabled</th>
|
||||
<?php if (extension_loaded('mbstring')): ?>
|
||||
<td class="pass">Pass</td>
|
||||
<?php else: $failed = TRUE; ?>
|
||||
<td class="fail">The <a href="http://php.net/mbstring">mbstring</a>
|
||||
extension is not loaded.</td>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
<?php if (extension_loaded('mbstring')): ?>
|
||||
<tr>
|
||||
<th>Mbstring Not Overloaded</th>
|
||||
<?php if (ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING): $failed = TRUE?>
|
||||
<td class="fail">
|
||||
The <a href="http://php.net/mbstring">mbstring</a>
|
||||
extension is overloading PHP's native string functions.
|
||||
</td>
|
||||
<?php else : ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<?php endif?>
|
||||
<tr>
|
||||
<th>XML support</th>
|
||||
<?php if ( ! function_exists('utf8_encode')): $failed = TRUE?>
|
||||
<td class="fail">
|
||||
PHP is compiled without <a href="http://php.net/xml">XML</a>
|
||||
support, thus lacking support for
|
||||
<code>
|
||||
utf8_encode()
|
||||
</code>/
|
||||
<code>
|
||||
utf8_decode()
|
||||
</code>.
|
||||
</td>
|
||||
<?php else : ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
<th>Timezone</th>
|
||||
<?php try { new DateTimeZone(ini_get('date.timezone')); ?>
|
||||
<td class="pass">Pass</td>
|
||||
<?php } catch (Exception $e) { $failed = TRUE ?>
|
||||
<td class="fail">
|
||||
The current timezone, <code>'<?php echo ini_get('date.timezone') ?>'</code>, is not valid.
|
||||
You must configure it in <code>php.ini</code> or <code>config/locale.php</code>.
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>URI Determination</th>
|
||||
<?php if (isset($_SERVER['SCRIPT_NAME']) AND (isset($_SERVER['PATH_INFO']) OR isset($_SERVER['ORIG_PATH_INFO']) OR isset($_SERVER['PHP_SELF']))): ?>
|
||||
<td class="pass">
|
||||
Pass
|
||||
</td>
|
||||
<?php else : $failed = TRUE?>
|
||||
<td class="fail">
|
||||
At least one of <code>$_SERVER['PATH_INFO']</code>, <code>$_SERVER['ORIG_PATH_INFO']</code>, or <code>$_SERVER['PHP_SELF']</code> must be available.
|
||||
</td>
|
||||
<?php endif?>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="results">
|
||||
<?php if ($failed === TRUE): ?>
|
||||
<p class="fail">
|
||||
Kohana may not work correctly with your environment.
|
||||
</p>
|
||||
<?php else : ?>
|
||||
<p class="pass">
|
||||
Your environment passed all requirements. Remove or rename the
|
||||
<code>
|
||||
install<?php echo EXT?>
|
||||
</code>
|
||||
file now.
|
||||
</p>
|
||||
<?php endif?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
30
web_client/Kohana License.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
|
||||
<title>Kohana License</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Kohana License Agreement</h2>
|
||||
|
||||
<p>This license is a legal agreement between you and the Kohana Software Foundation for the use of Kohana Framework (the "Software"). By obtaining the Software you agree to comply with the terms and conditions of this license.</p>
|
||||
|
||||
<p>Copyright (c) 2007-2009 Kohana Team<br/>All rights reserved.</p>
|
||||
|
||||
<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
|
||||
|
||||
<ul>
|
||||
<li>Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</li>
|
||||
<li>Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</li>
|
||||
<li>Neither the name of the Kohana nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.</li>
|
||||
</ul>
|
||||
|
||||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
|
||||
|
||||
<p><small>NOTE: This license is modeled after the BSD software license.</small></p>
|
||||
|
||||
</body>
|
||||
</html>
|
59
web_client/application/Bootstrap.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Kohana process control file, loaded by the front controller.
|
||||
*
|
||||
* $Id: Bootstrap.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
|
||||
// Kohana benchmarks are prefixed to prevent collisions
|
||||
define('SYSTEM_BENCHMARK', 'system_benchmark');
|
||||
|
||||
// Load benchmarking support
|
||||
require SYSPATH.'core/Benchmark'.EXT;
|
||||
|
||||
// Start total_execution
|
||||
Benchmark::start(SYSTEM_BENCHMARK.'_total_execution');
|
||||
|
||||
// Start kohana_loading
|
||||
Benchmark::start(SYSTEM_BENCHMARK.'_kohana_loading');
|
||||
|
||||
// Load core files
|
||||
require SYSPATH.'core/Event'.EXT;
|
||||
final class Event extends Event_Core {}
|
||||
|
||||
require SYSPATH.'core/Kohana'.EXT;
|
||||
final class Kohana extends Kohana_Core {}
|
||||
|
||||
require SYSPATH.'core/Kohana_Exception'.EXT;
|
||||
class Kohana_Exception extends Kohana_Exception_Core {}
|
||||
|
||||
require SYSPATH.'core/Kohana_Config'.EXT;
|
||||
require SYSPATH.'libraries/drivers/Config'.EXT;
|
||||
require SYSPATH.'libraries/drivers/Config/Array'.EXT;
|
||||
final class Kohana_Config extends Kohana_Config_Core {}
|
||||
|
||||
// Prepare the environment
|
||||
Kohana::setup();
|
||||
|
||||
// End kohana_loading
|
||||
Benchmark::stop(SYSTEM_BENCHMARK.'_kohana_loading');
|
||||
|
||||
// Start system_initialization
|
||||
Benchmark::start(SYSTEM_BENCHMARK.'_system_initialization');
|
||||
|
||||
// Prepare the system
|
||||
Event::run('system.ready');
|
||||
|
||||
// Determine routing
|
||||
Event::run('system.routing');
|
||||
|
||||
// End system_initialization
|
||||
Benchmark::stop(SYSTEM_BENCHMARK.'_system_initialization');
|
||||
|
||||
// Make the magic happen!
|
||||
Event::run('system.execute');
|
1
web_client/application/cache/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*
|
118
web_client/application/config/config.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Base path of the web site. If this includes a domain, eg: localhost/kohana/
|
||||
* then a full URL will be used, eg: http://localhost/kohana/. If it only includes
|
||||
* the path, and a site_protocol is specified, the domain will be auto-detected.
|
||||
*/
|
||||
$config['site_domain'] = '/g3_client/';
|
||||
|
||||
/**
|
||||
* Force a default protocol to be used by the site. If no site_protocol is
|
||||
* specified, then the current protocol is used, or when possible, only an
|
||||
* absolute path (with no protocol/domain) is used.
|
||||
*/
|
||||
$config['site_protocol'] = '';
|
||||
|
||||
/**
|
||||
* Name of the front controller for this application. Default: index.php
|
||||
*
|
||||
* This can be removed by using URL rewriting.
|
||||
*/
|
||||
$config['index_page'] = 'index.php';
|
||||
|
||||
/**
|
||||
* Fake file extension that will be added to all generated URLs. Example: .html
|
||||
*/
|
||||
$config['url_suffix'] = '';
|
||||
|
||||
/**
|
||||
* Length of time of the internal cache in seconds. 0 or FALSE means no caching.
|
||||
* The internal cache stores file paths and config entries across requests and
|
||||
* can give significant speed improvements at the expense of delayed updating.
|
||||
*/
|
||||
$config['internal_cache'] = FALSE;
|
||||
|
||||
/**
|
||||
* Internal cache directory.
|
||||
*/
|
||||
$config['internal_cache_path'] = APPPATH.'cache/';
|
||||
|
||||
/**
|
||||
* Enable internal cache encryption - speed/processing loss
|
||||
* is neglible when this is turned on. Can be turned off
|
||||
* if application directory is not in the webroot.
|
||||
*/
|
||||
$config['internal_cache_encrypt'] = TRUE;
|
||||
|
||||
/**
|
||||
* Encryption key for the internal cache, only used
|
||||
* if internal_cache_encrypt is TRUE.
|
||||
*
|
||||
* Make sure you specify your own key here!
|
||||
*
|
||||
* The cache is deleted when/if the key changes.
|
||||
*/
|
||||
$config['internal_cache_key'] = 'g3_client';
|
||||
|
||||
/**
|
||||
* Enable or disable gzip output compression. This can dramatically decrease
|
||||
* server bandwidth usage, at the cost of slightly higher CPU usage. Set to
|
||||
* the compression level (1-9) that you want to use, or FALSE to disable.
|
||||
*
|
||||
* Do not enable this option if you are using output compression in php.ini!
|
||||
*/
|
||||
$config['output_compression'] = FALSE;
|
||||
|
||||
/**
|
||||
* Enable or disable global XSS filtering of GET, POST, and SERVER data. This
|
||||
* option also accepts a string to specify a specific XSS filtering tool.
|
||||
*/
|
||||
$config['global_xss_filtering'] = FALSE;
|
||||
|
||||
/**
|
||||
* Enable or disable hooks.
|
||||
*/
|
||||
$config['enable_hooks'] = FALSE;
|
||||
/**
|
||||
* Enable or disable displaying of Kohana error pages. This will not affect
|
||||
* logging. Turning this off will disable ALL error pages.
|
||||
*/
|
||||
$config['display_errors'] = TRUE;
|
||||
|
||||
/**
|
||||
* Enable or disable statistics in the final output. Stats are replaced via
|
||||
* specific strings, such as {execution_time}.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/general/configuration
|
||||
*/
|
||||
$config['render_stats'] = TRUE;
|
||||
|
||||
/**
|
||||
* Filename prefixed used to determine extensions. For example, an
|
||||
* extension to the Controller class would be named MY_Controller.php.
|
||||
*/
|
||||
$config['extension_prefix'] = 'MY_';
|
||||
|
||||
/**
|
||||
* An optional list of Config Drivers to use, they "fallback" to the one below them if they
|
||||
* dont work so the first driver is tried then so on until it hits the built in "array" driver and fails
|
||||
*/
|
||||
$config['config_drivers'] = array();
|
||||
|
||||
/**
|
||||
* Additional resource paths, or "modules". Each path can either be absolute
|
||||
* or relative to the docroot. Modules can include any resource that can exist
|
||||
* in your application directory, configuration files, controllers, views, etc.
|
||||
*/
|
||||
$config['modules'] = array
|
||||
(
|
||||
// MODPATH.'auth', // Authentication
|
||||
// MODPATH.'forge', // Form generation
|
||||
// MODPATH.'kodoc', // Self-generating documentation
|
||||
// MODPATH.'media', // Media caching and compression
|
||||
// MODPATH.'gmaps', // Google Maps integration
|
||||
// MODPATH.'archive', // Archive utility
|
||||
// MODPATH.'payment', // Online payments
|
||||
// MODPATH.'unit_test', // Unit testing
|
||||
// MODPATH.'object_db', // New OOP Database library (testing only!)
|
||||
);
|
5
web_client/application/config/g3_remote.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Base path of the gallery3 web site
|
||||
*/
|
||||
$config["gallery3_site"] = "http://sandbox.timalmdal.com/gallery3/index.php/rest";
|
7
web_client/application/config/routes.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* Sets the default route to "welcome"
|
||||
*/
|
||||
$config['_default'] = 'g3_client';
|
99
web_client/application/controllers/g3_client.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Gallery - a web based photo album viewer and editor
|
||||
* Copyright (C) 2000-2009 Bharat Mediratta
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
class G3_Client_Controller extends Template_Controller {
|
||||
// Set the name of the template to use
|
||||
public $template = 'g3_template.html';
|
||||
|
||||
public function index() {
|
||||
$this->template->title = 'G3 Web Client';
|
||||
|
||||
if (Session::instance()->get("g3_client_access_token")) {
|
||||
$resource = G3Remote::instance()->get_resource("gallery");
|
||||
$this->template->album_tree = $this->_get_album_tree($resource);
|
||||
$this->template->detail = $this->_get_detail($resource);
|
||||
} else {
|
||||
$this->template->content = new View('login.html');
|
||||
$this->template->content->errors = $this->template->content->form =
|
||||
array("user" => "", "password" => "");
|
||||
}
|
||||
}
|
||||
|
||||
public function login() {
|
||||
$form = $errors = array("user" => "", "password" => "");
|
||||
$post = new Validation($_POST);
|
||||
$post->add_rules("user", "required");
|
||||
$post->add_rules("password", "required");
|
||||
if ($valid =$post->validate()) {
|
||||
try {
|
||||
$token = G3Remote::instance()->get_access_token($post["user"], $post["password"]);
|
||||
Session::instance()->set("g3_client_access_token", $token);
|
||||
$resource = G3Remote::instance()->get_resource("gallery");
|
||||
$content = array(
|
||||
"album_tree" => $this->_get_album_tree($resource),
|
||||
"detail" => $this->_get_detail($resource));
|
||||
} catch (Exception $e) {
|
||||
Kohana_Log::add("error", Kohana_Exception::text($e));
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$valid) {
|
||||
$content = new View('login.html');
|
||||
$content->form = arr::overwrite($form, $post->as_array());
|
||||
$content->errors = arr::overwrite($errors, $post->errors());
|
||||
}
|
||||
|
||||
$this->auto_render = false;
|
||||
print json_encode(array("status" => $valid ? "ok" : "error", "content" => $content));
|
||||
}
|
||||
|
||||
public function albums() {
|
||||
$path = $this->input->get("path");
|
||||
$resource = G3Remote::instance()->get_resource("gallery/$path", "album");
|
||||
$this->auto_render = false;
|
||||
print $this->_get_album_tree($resource);
|
||||
}
|
||||
|
||||
public function detail() {
|
||||
$path = $this->input->get("path");
|
||||
$resource = G3Remote::instance()->get_resource("gallery/$path");
|
||||
$this->auto_render = false;
|
||||
print $this->_get_detail($resource);
|
||||
}
|
||||
|
||||
private function _get_album_tree($resource) {
|
||||
$v = new View("tree_part.html");
|
||||
$v->element = (object)array("title" => $resource->title, "path" => $resource->path);
|
||||
$v->element->children = array();
|
||||
foreach ($resource->children as $child) {
|
||||
if ($child->type != "album") {
|
||||
continue;
|
||||
}
|
||||
$v->element->children[] = $child;
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
|
||||
private function _get_detail($resource) {
|
||||
$v = new View("{$resource->type}_detail.html");
|
||||
$v->resource = $resource;
|
||||
return $v;
|
||||
}
|
||||
} // End G3 Client Controller
|
252
web_client/application/libraries/G3Remote.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Gallery - a web based photo album viewer and editor
|
||||
* Copyright (C) 2000-2009 Bharat Mediratta
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
class url_connection {
|
||||
static function post($url, $post_data_array, $extra_headers=array()) {
|
||||
$_data_raw = self::_encode_data($post_data_array, $extra_headers);
|
||||
|
||||
$extra_headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
$extra_headers['Content-Length'] = strlen($_data_raw);
|
||||
|
||||
/* Read the web page into a buffer */
|
||||
list ($response_status, $response_headers, $response_body) =
|
||||
self::do_request($url, 'POST', $extra_headers, $post_data_raw);
|
||||
|
||||
return array($response_body, $response_status, $response_headers);
|
||||
}
|
||||
|
||||
static function get($url, $_data_array=array(), $extra_headers=array()) {
|
||||
$_data_raw = self::_encode_data($_data_array, $extra_headers);
|
||||
|
||||
/* Read the web page into a buffer */
|
||||
list ($response_status, $response_headers, $response_body) =
|
||||
self::do_request("{$url}?$_data_raw", "GET", $extra_headers);
|
||||
|
||||
return array($response_body, $response_status, $response_headers);
|
||||
}
|
||||
|
||||
static function success($response_status) {
|
||||
return preg_match("/^HTTP\/\d+\.\d+\s2\d{2}(\s|$)/", trim($response_status));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the data. For each key/value pair, urlencode both the key and the value and then
|
||||
* concatenate together. As per the specification, each key/value pair is separated with an
|
||||
* ampersand (&)
|
||||
* @param array $data_array the key/value data
|
||||
* @param array $extra_headers extra headers to pass to the server
|
||||
* @return string the encoded post data
|
||||
*/
|
||||
private static function _encode_data($_data_array, &$extra_headers) {
|
||||
$_data_raw = '';
|
||||
foreach ($_data_array as $key => $value) {
|
||||
if (!empty($_data_raw)) {
|
||||
$_data_raw .= '&';
|
||||
}
|
||||
$_data_raw .= urlencode($key) . '=' . urlencode($value);
|
||||
}
|
||||
|
||||
return $_data_raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* A single request, without following redirects
|
||||
*
|
||||
* @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's
|
||||
* WebHelper_simple::_parseLocation logic.
|
||||
*/
|
||||
static function do_request($url, $method='GET', $headers=array(), $body='') {
|
||||
/* Convert illegal characters */
|
||||
$url = str_replace(' ', '%20', $url);
|
||||
|
||||
$url_components = self::_parse_url_for_fsockopen($url);
|
||||
$handle = fsockopen(
|
||||
$url_components['fsockhost'], $url_components['port'], $errno, $errstr, 5);
|
||||
if (empty($handle)) {
|
||||
// log "Error $errno: '$errstr' requesting $url";
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
$header_lines = array('Host: ' . $url_components['host']);
|
||||
foreach ($headers as $key => $value) {
|
||||
$header_lines[] = $key . ': ' . $value;
|
||||
}
|
||||
|
||||
$success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n%s",
|
||||
$method,
|
||||
$url_components['uri'],
|
||||
implode("\r\n", $header_lines),
|
||||
$body));
|
||||
if (!$success) {
|
||||
// Zero bytes written or false was returned
|
||||
// log "fwrite failed in requestWebPage($url)" . ($success === false ? ' - false' : ''
|
||||
return array(null, null, null);
|
||||
}
|
||||
fflush($handle);
|
||||
|
||||
/*
|
||||
* Read the status line. fgets stops after newlines. The first line is the protocol
|
||||
* version followed by a numeric status code and its associated textual phrase.
|
||||
*/
|
||||
$response_status = trim(fgets($handle, 4096));
|
||||
if (empty($response_status)) {
|
||||
// 'Empty http response code, maybe timeout'
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
/* Read the headers */
|
||||
$response_headers = array();
|
||||
while (!feof($handle)) {
|
||||
$line = trim(fgets($handle, 4096));
|
||||
if (empty($line)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Normalize the line endings */
|
||||
$line = str_replace("\r", '', $line);
|
||||
|
||||
list ($key, $value) = explode(':', $line, 2);
|
||||
if (isset($response_headers[$key])) {
|
||||
if (!is_array($response_headers[$key])) {
|
||||
$response_headers[$key] = array($response_headers[$key]);
|
||||
}
|
||||
$response_headers[$key][] = trim($value);
|
||||
} else {
|
||||
$response_headers[$key] = trim($value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the body */
|
||||
$response_body = '';
|
||||
while (!feof($handle)) {
|
||||
$response_body .= fread($handle, 4096);
|
||||
}
|
||||
fclose($handle);
|
||||
|
||||
return array($response_status, $response_headers, $response_body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for fsockopen call.
|
||||
* @param string $url
|
||||
* @return array url components
|
||||
* @access private
|
||||
*/
|
||||
private static function _parse_url_for_fsockopen($url) {
|
||||
$url_components = parse_url($url);
|
||||
if (strtolower($url_components['scheme']) == 'https') {
|
||||
$url_components['fsockhost'] = 'ssl://' . $url_components['host'];
|
||||
$default_port = 443;
|
||||
} else {
|
||||
$url_components['fsockhost'] = $url_components['host'];
|
||||
$default_port = 80;
|
||||
}
|
||||
if (empty($url_components['port'])) {
|
||||
$url_components['port'] = $default_port;
|
||||
}
|
||||
if (empty($url_components['path'])) {
|
||||
$url_components['path'] = '/';
|
||||
}
|
||||
$uri = $url_components['path']
|
||||
. (empty($url_components['query']) ? '' : '?' . $url_components['query']);
|
||||
/* Unescape ampersands, since if the url comes from form input it will be escaped */
|
||||
$url_components['uri'] = str_replace('&', '&', $uri);
|
||||
|
||||
return $url_components;
|
||||
}
|
||||
}
|
||||
|
||||
// This class does not depend on any Kohana services so that it can be used in non-Kohana
|
||||
// applications.
|
||||
class G3Remote {
|
||||
protected static $_instance;
|
||||
|
||||
protected $_config;
|
||||
|
||||
private $_resources;
|
||||
private $_access_token;
|
||||
private $_identity;
|
||||
|
||||
public static function instance($access_token=null) {
|
||||
if (!isset(G3Remote::$_instance)) {
|
||||
G3Remote::$_instance = new G3Remote($access_token);
|
||||
}
|
||||
|
||||
return G3Remote::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new G3Remote object
|
||||
*
|
||||
* @param array Database config array
|
||||
* @return G3Remote
|
||||
*/
|
||||
protected function __construct($access_token) {
|
||||
// Store the config locally
|
||||
$this->_config = Kohana::config("g3_remote");
|
||||
$this->_access_token = $access_token;
|
||||
}
|
||||
|
||||
public function get_access_token($user, $password) {
|
||||
$identity = md5("$user/$password");
|
||||
if (empty($this->_identity) || $this->_identity != $identity) {
|
||||
$request = "{$this->_config["gallery3_site"]}/access_key";
|
||||
list ($response_body, $response_status, $response_headers) =
|
||||
url_connection::get($request, array("user" => $user, "password" => $password));
|
||||
if (url_connection::success($response_status)) {
|
||||
$response = json_decode($response_body);
|
||||
if ($response->status == "OK") {
|
||||
$this->_access_token = $response->token;
|
||||
$this->_identity = $identity;
|
||||
} else {
|
||||
throw new Exception("Remote host failure: {$response->message}");
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Remote host failure: $response_status");
|
||||
}
|
||||
}
|
||||
return $this->_access_token;
|
||||
}
|
||||
|
||||
public function get_resource($path, $filter=false, $offset=false, $limit=false) {
|
||||
$request = "{$this->_config["gallery3_site"]}/$path";
|
||||
$params = array();
|
||||
if ($filter) {
|
||||
$param["filter"] = $filter;
|
||||
}
|
||||
if ($offset) {
|
||||
$param["offset"] = $offset;
|
||||
}
|
||||
if ($limit) {
|
||||
$param["limit"] = $limit;
|
||||
}
|
||||
|
||||
list ($response_body, $response_status, $response_headers) =
|
||||
url_connection::get($request, $params);
|
||||
if (url_connection::success($response_status)) {
|
||||
$response = json_decode($response_body);
|
||||
if ($response->status != "OK") {
|
||||
throw new Exception("Remote host failure: {$response->message}");
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Remote host failure: $response_status");
|
||||
}
|
||||
return $response->resource;
|
||||
}
|
||||
}
|
1
web_client/application/logs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*
|
15
web_client/application/views/album_detail.html.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php defined("SYSPATH") or die("No direct script access.") ?>
|
||||
<ul id="thumb-grid" class="ui-helper-clearfix">
|
||||
<? foreach ($resource->children as $child): ?>
|
||||
<li class="thumb-grid-cell" ref="<?= $child->path ?>">
|
||||
<a href="g3_client/show/<?= $child->path ?>">
|
||||
<? if ($child->has_thumb): ?>
|
||||
<img src="<?= $child->thumb_url ?>" title="<?= $child->title ?>" />
|
||||
<? else: ?>
|
||||
<span><?= $child->title ?></span>
|
||||
<? endif ?>
|
||||
</a>
|
||||
</li>
|
||||
<? endforeach ?>
|
||||
</ul>
|
||||
|
49
web_client/application/views/g3_template.html.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.'); ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<title><?= html::chars(__($title)) ?></title>
|
||||
<?= html::stylesheet("css/reset-fonts-grids.css") ?>
|
||||
<?= html::stylesheet("css/g3_client.css") ?>
|
||||
<?= html::stylesheet("css/jquery-ui.css") ?>
|
||||
<!--[if lt IE 8]>
|
||||
<link rel="stylesheet" type="text/css" href="<?= url::file("css/fix-ie.css") ?>"
|
||||
media="screen,print,projection" />
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.copyright { font-size: 0.9em; text-transform: uppercase; color: #557d10; }
|
||||
</style>
|
||||
<?= html::script("js/jquery.js") ?>
|
||||
<?= html::script("js/jquery.form.js") ?>
|
||||
<?= html::script("js/jquery-ui.js") ?>
|
||||
<?= html::script("js/g3_client.js") ?>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$("#body div").gallery3_client();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="doc4" class="yui-t5">
|
||||
<div id="header" class="ui-helper-clearfix">
|
||||
<div> </div>
|
||||
</div>
|
||||
<div id="body">
|
||||
<div id="left">
|
||||
<ul id="album_tree"><?= $album_tree ?></ul>
|
||||
</div>
|
||||
<div id="center">
|
||||
<?= $detail ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="ui-helper-clearfix">
|
||||
<p class="copyright">
|
||||
<?= __('Rendered in {execution_time} seconds, using {memory_usage} of memory')?><br />
|
||||
Copyright ©2009–2010 Gallery Team
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
27
web_client/application/views/login.html.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php defined("SYSPATH") or die("No direct script access.") ?>
|
||||
<ul>
|
||||
<li id="g-login-form">
|
||||
<?= form::open("g3_client/login") ?>
|
||||
<fieldset>
|
||||
<legend>Please provide your userid and password for the remote system</legend>
|
||||
<ul>
|
||||
<li>
|
||||
<?= form::label("user", "User Id:") ?><br/>
|
||||
<?= form::input("user", $form["user"]) ?>
|
||||
<?= empty($errors["user"]) ? "" : "<span class=\"error\">{$errors["user"]}</span>" ?>
|
||||
</li>
|
||||
<li>
|
||||
<?= form::label("password", "Password") ?><br/>
|
||||
<?= form::password("password", $form["password"]) ?>
|
||||
<?= empty($errors["password"]) ? "" : "<span class=\"error\">{$errors["password"]}</span>" ?>
|
||||
</li>
|
||||
<li>
|
||||
<?= form::submit("submit", "Login") ?>
|
||||
<?= form::input(array('type'=>'reset','name'=>'reset'), "Reset") ?>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
|
14
web_client/application/views/tree_part.html.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php defined("SYSPATH") or die("No direct script access.") ?>
|
||||
<li class="ui-icon-left" ref="<?= $element->path ?>">
|
||||
<span class="<?= count($element->children) > 0 ? "ui-icon ui-icon-minus" : "ui-icon-none" ?>" > </span>
|
||||
<span class="tree-title"><?= $element->title ?></span>
|
||||
<ul class="ui-helper-clearfix tree-chidren">
|
||||
<? foreach ($element->children as $child): ?>
|
||||
<li ref="<?= $child->path ?>" class="ui-icon-left">
|
||||
<span class="<?= $child->has_children ? "ui-icon ui-icon-plus" : "ui-icon-none" ?>"> </span>
|
||||
<span class="tree-title"><?= $child->title ?></span>
|
||||
</li>
|
||||
<? endforeach ?>
|
||||
</ul>
|
||||
</li>
|
||||
|
15
web_client/application/views/welcome_content.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.'); ?>
|
||||
<div class="box">
|
||||
<p><?php echo __('This is the default Kohana index page. You may also access this page as')?> <code><?php echo html::anchor('welcome/index', 'welcome/index') ?></code>.</p>
|
||||
|
||||
<p>
|
||||
<?php echo __('To change what gets displayed for this page, edit')?> <code>application/controllers/welcome.php</code>.<br />
|
||||
<?php echo __('To change this text, edit')?> <code>application/views/welcome_content.php</code>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<?php foreach ($links as $title => $url): ?>
|
||||
<li><?php echo ($title === 'License') ? html::file_anchor($url, html::chars(__($title))) : html::anchor($url, html::chars(__($title))) ?></li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
29
web_client/css/fix-ie.css
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Fix display in IE 6, 7
|
||||
*/
|
||||
|
||||
#g-banner {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
input.submit {
|
||||
clear: none !important;
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
#g-add-tag-form input.textbox {
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
#g-dialog .g-cancel {
|
||||
display: inline-block !important;
|
||||
float: none !important;
|
||||
}
|
||||
|
||||
.g-paginator .g-text-right {
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
.g-paginator .ui-icon-right {
|
||||
width: 60px;
|
||||
}
|
118
web_client/css/g3_client.css
Normal file
@ -0,0 +1,118 @@
|
||||
#header {
|
||||
background-color: #E8E8E8;
|
||||
left: 0px;
|
||||
min-height: 90px;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
#header div {
|
||||
background-image: url(g3_web.png);
|
||||
background-repeat: no-repeat;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
#body {
|
||||
background-color: #E8E8E8;
|
||||
bottom: 40px;
|
||||
left: 0px;
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
top: 90px;
|
||||
}
|
||||
|
||||
#body #content {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #CCCCCC;
|
||||
padding: 10px 20px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
form li {
|
||||
padding-top: .4em;
|
||||
}
|
||||
|
||||
form legend {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.error {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
#footer {
|
||||
background-color: #E8E8E8;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
min-height: 40px;
|
||||
padding: 10px 20px;
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
font-size: 0.9em;
|
||||
text-transform: uppercase;
|
||||
color: #557d10;
|
||||
}
|
||||
|
||||
#body #left {
|
||||
background-color: #FFFFFF;
|
||||
border: 2px inset;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
width: 191px;
|
||||
}
|
||||
|
||||
#body #left #album_tree {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
#body #left #album_tree ul li {
|
||||
padding: 0 0 .2em 1.2em;
|
||||
}
|
||||
|
||||
#body #center {
|
||||
background-color: #FFFFFF;
|
||||
border: 2px inset;
|
||||
bottom: 20px;
|
||||
left: 225px;
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 11px;
|
||||
}
|
||||
|
||||
.tree-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#body #center .thumb-grid-cell {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.ui-icon-left .ui-icon {
|
||||
float: left;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.ui-icon-left .ui-icon-none {
|
||||
float: left;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.ui-selected {
|
||||
background-color: #E8E8E8;
|
||||
color: #FF9933;
|
||||
}
|
BIN
web_client/css/g3_web.pdn
Normal file
BIN
web_client/css/g3_web.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
web_client/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
web_client/css/images/ui-bg_diagonals-thick_20_666666_40x40.png
Normal file
After Width: | Height: | Size: 251 B |
BIN
web_client/css/images/ui-bg_flat_10_000000_40x100.png
Normal file
After Width: | Height: | Size: 178 B |
BIN
web_client/css/images/ui-bg_glass_100_f6f6f6_1x400.png
Normal file
After Width: | Height: | Size: 104 B |
BIN
web_client/css/images/ui-bg_glass_100_fdf5ce_1x400.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
web_client/css/images/ui-bg_glass_65_ffffff_1x400.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
web_client/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
web_client/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
Normal file
After Width: | Height: | Size: 90 B |
BIN
web_client/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
web_client/css/images/ui-icons_222222_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
web_client/css/images/ui-icons_228ef1_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
web_client/css/images/ui-icons_ef8c08_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
web_client/css/images/ui-icons_ffd27a_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
web_client/css/images/ui-icons_ffffff_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
406
web_client/css/jquery-ui.css
vendored
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
* jQuery UI CSS Framework
|
||||
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
.ui-helper-clearfix { display: inline-block; }
|
||||
/* required comment for clearfix to work in Opera \*/
|
||||
* html .ui-helper-clearfix { height:1%; }
|
||||
.ui-helper-clearfix { display:block; }
|
||||
/* end clearfix */
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* jQuery UI CSS Framework
|
||||
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
|
||||
*/
|
||||
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
|
||||
.ui-widget-content a { color: #333333; }
|
||||
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
|
||||
.ui-widget-header a { color: #ffffff; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; outline: none; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; outline: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; outline: none; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; outline: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; outline: none; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; outline: none; text-decoration: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a { color: #ffffff; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
|
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
|
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
|
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
|
||||
.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
|
||||
.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
|
||||
.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
|
||||
.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
|
||||
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
|
||||
.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
|
||||
.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
|
||||
.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; }/* Accordion
|
||||
----------------------------------*/
|
||||
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
|
||||
.ui-accordion .ui-accordion-li-fix { display: inline; }
|
||||
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
|
||||
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
|
||||
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
||||
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
|
||||
.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
|
||||
----------------------------------*/
|
||||
.ui-datepicker { width: 17em; padding: .2em .2em 0; }
|
||||
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
||||
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
||||
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
||||
.ui-datepicker .ui-datepicker-next { right:2px; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
||||
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
||||
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
||||
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
||||
.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
|
||||
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
||||
.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
|
||||
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
||||
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
||||
.ui-datepicker td { border: 0; padding: 1px; }
|
||||
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
||||
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
||||
.ui-datepicker-row-break { clear:both; width:100%; }
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl { direction: rtl; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
|
||||
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
||||
.ui-datepicker-cover {
|
||||
display: none; /*sorry for IE5*/
|
||||
display/**/: block; /*sorry for IE5*/
|
||||
position: absolute; /*must have*/
|
||||
z-index: -1; /*must have*/
|
||||
filter: mask(); /*must have*/
|
||||
top: -4px; /*must have*/
|
||||
left: -4px; /*must have*/
|
||||
width: 200px; /*must have*/
|
||||
height: 200px; /*must have*/
|
||||
}/* Dialog
|
||||
----------------------------------*/
|
||||
.ui-dialog { position: relative; padding: .2em; width: 300px; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
||||
/* Progressbar
|
||||
----------------------------------*/
|
||||
.ui-progressbar { height:2em; text-align: left; }
|
||||
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
|
||||
----------------------------------*/
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
|
||||
----------------------------------*/
|
||||
.ui-slider { position: relative; text-align: left; }
|
||||
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
||||
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
|
||||
|
||||
.ui-slider-horizontal { height: .8em; }
|
||||
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
||||
|
||||
.ui-slider-vertical { width: .8em; height: 100px; }
|
||||
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
|
||||
----------------------------------*/
|
||||
.ui-tabs { padding: .2em; zoom: 1; }
|
||||
.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
|
||||
.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
|
||||
.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
|
||||
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
||||
.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
|
||||
.ui-tabs .ui-tabs-hide { display: none !important; }
|
BIN
web_client/css/kohana-2.4rc2.zip
Normal file
7
web_client/css/reset-fonts-grids.css
Normal file
19
web_client/example.htaccess
Normal file
@ -0,0 +1,19 @@
|
||||
# Turn on URL rewriting
|
||||
RewriteEngine On
|
||||
|
||||
# Installation directory
|
||||
RewriteBase /kohana/
|
||||
|
||||
# Protect application and system files from being viewed
|
||||
# This is only necessary when these files are inside the webserver document root
|
||||
RewriteRule ^(application|modules|system) - [R=404,L]
|
||||
|
||||
# Allow any files or directories that exist to be displayed directly
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# Rewrite all other URLs to index.php/URL
|
||||
RewriteRule .* index.php/$0 [PT,L]
|
||||
|
||||
# Alternativly, if the rewrite rule above does not work try this instead:
|
||||
#RewriteRule .* index.php?kohana_uri=$0 [PT,QSA,L]
|
107
web_client/index.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* This file acts as the "front controller" to your application. You can
|
||||
* configure your application, modules, and system directories here.
|
||||
* PHP error_reporting level may also be changed.
|
||||
*
|
||||
* @see http://kohanaphp.com
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define the website environment status. When this flag is set to TRUE, some
|
||||
* module demonstration controllers will result in 404 errors. For more information
|
||||
* about this option, read the documentation about deploying Kohana.
|
||||
*
|
||||
* @see http://docs.kohanaphp.com/installation/deployment
|
||||
*/
|
||||
define('IN_PRODUCTION', FALSE);
|
||||
|
||||
/**
|
||||
* Website application directory. This directory should contain your application
|
||||
* configuration, controllers, models, views, and other resources.
|
||||
*
|
||||
* This path can be absolute or relative to this file.
|
||||
*/
|
||||
$kohana_application = 'application';
|
||||
|
||||
/**
|
||||
* Kohana modules directory. This directory should contain all the modules used
|
||||
* by your application. Modules are enabled and disabled by the application
|
||||
* configuration file.
|
||||
*
|
||||
* This path can be absolute or relative to this file.
|
||||
*/
|
||||
$kohana_modules = 'modules';
|
||||
|
||||
/**
|
||||
* Kohana system directory. This directory should contain the core/ directory,
|
||||
* and the resources you included in your download of Kohana.
|
||||
*
|
||||
* This path can be absolute or relative to this file.
|
||||
*/
|
||||
$kohana_system = 'system';
|
||||
|
||||
/**
|
||||
* Test to make sure that Kohana is running on PHP 5.2 or newer. Once you are
|
||||
* sure that your environment is compatible with Kohana, you can comment this
|
||||
* line out. When running an application on a new server, uncomment this line
|
||||
* to check the PHP version quickly.
|
||||
*/
|
||||
version_compare(PHP_VERSION, '5.2', '<') and exit('Kohana requires PHP 5.2 or newer.');
|
||||
|
||||
/**
|
||||
* Set the error reporting level. Unless you have a special need, E_ALL is a
|
||||
* good level for error reporting.
|
||||
*/
|
||||
error_reporting(E_ALL & ~E_STRICT);
|
||||
|
||||
/**
|
||||
* Turning off display_errors will effectively disable Kohana error display
|
||||
* and logging. You can turn off Kohana errors in application/config/config.php
|
||||
*/
|
||||
ini_set('display_errors', TRUE);
|
||||
|
||||
/**
|
||||
* If you rename all of your .php files to a different extension, set the new
|
||||
* extension here. This option can left to .php, even if this file has a
|
||||
* different extension.
|
||||
*/
|
||||
define('EXT', '.php');
|
||||
|
||||
//
|
||||
// DO NOT EDIT BELOW THIS LINE, UNLESS YOU FULLY UNDERSTAND THE IMPLICATIONS.
|
||||
// ----------------------------------------------------------------------------
|
||||
// $Id: index.php 4587 2009-09-10 16:45:21Z isaiah $
|
||||
//
|
||||
|
||||
$kohana_pathinfo = pathinfo(__FILE__);
|
||||
// Define the front controller name and docroot
|
||||
define('DOCROOT', $kohana_pathinfo['dirname'].DIRECTORY_SEPARATOR);
|
||||
define('KOHANA', $kohana_pathinfo['basename']);
|
||||
|
||||
// If the front controller is a symlink, change to the real docroot
|
||||
is_link(KOHANA) and chdir(dirname(realpath(__FILE__)));
|
||||
|
||||
// If kohana folders are relative paths, make them absolute.
|
||||
$kohana_application = file_exists($kohana_application) ? $kohana_application : DOCROOT.$kohana_application;
|
||||
$kohana_modules = file_exists($kohana_modules) ? $kohana_modules : DOCROOT.$kohana_modules;
|
||||
$kohana_system = file_exists($kohana_system) ? $kohana_system : DOCROOT.$kohana_system;
|
||||
|
||||
// Define application and system paths
|
||||
define('APPPATH', str_replace('\\', '/', realpath($kohana_application)).'/');
|
||||
define('MODPATH', str_replace('\\', '/', realpath($kohana_modules)).'/');
|
||||
define('SYSPATH', str_replace('\\', '/', realpath($kohana_system)).'/');
|
||||
|
||||
// Clean up
|
||||
unset($kohana_application, $kohana_modules, $kohana_system);
|
||||
|
||||
if (file_exists(DOCROOT.'install'.EXT) AND is_readable(DOCROOT.'install'.EXT))
|
||||
{
|
||||
// Load the installation tests
|
||||
include DOCROOT.'install'.EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize Kohana
|
||||
require APPPATH.'Bootstrap'.EXT;
|
||||
}
|
67
web_client/js/g3_client.js
Normal file
@ -0,0 +1,67 @@
|
||||
(function($) {
|
||||
var _current_path = "";
|
||||
|
||||
$.fn.gallery3_client = function() {
|
||||
return this.each(function(i) {
|
||||
ajaxifyLoginForm(this);
|
||||
});
|
||||
};
|
||||
|
||||
function ajaxifyLoginForm(obj) {
|
||||
var login = $(obj).find("#g-login-form form");
|
||||
if (login.length > 0) {
|
||||
$(login).ajaxForm({
|
||||
dataType: "json",
|
||||
beforeSubmit: function(formData, form, options) {
|
||||
form.find(":submit")
|
||||
.addClass("ui-state-disabled")
|
||||
.attr("disabled", "disabled");
|
||||
return true;
|
||||
},
|
||||
success: function(data) {
|
||||
$(obj).html(data.content);
|
||||
if (data.status == "ok") {
|
||||
initializeDetail(obj);
|
||||
} else {
|
||||
ajaxifyLoginForm(obj);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
initializeDetail(obj);
|
||||
}
|
||||
};
|
||||
|
||||
function initializeDetail(obj) {
|
||||
$(".ui-icon-plus", obj).live("click", function (event) {
|
||||
var siblings = $("~ ul", this);
|
||||
if (siblings.length > 0) {
|
||||
siblings.show();
|
||||
$(this).removeClass("ui-icon-plus");
|
||||
$(this).addClass("ui-icon-minus");
|
||||
} else {
|
||||
var parent = $(this).parent("li");
|
||||
$.get("/g3_client/index.php/g3_client/albums",
|
||||
{path: $(parent).attr("ref")},
|
||||
function(data, textStatus) {
|
||||
$(parent).replaceWith(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
$(".ui-icon-minus", obj).live("click", function (event) {
|
||||
$("~ ul", this).hide();
|
||||
$(this).removeClass("ui-icon-minus");
|
||||
$(this).addClass("ui-icon-plus");
|
||||
});
|
||||
$(".tree-title", obj).click(function (event) {
|
||||
$.get("/g3_client/index.php/g3_client/detail",
|
||||
{path: $(this).parent("li").attr("ref")},
|
||||
function(data, textStatus) {
|
||||
$("#center").html(data);
|
||||
});
|
||||
$(".ui-selected").removeClass("ui-selected");
|
||||
$(this).addClass("ui-selected");
|
||||
});
|
||||
$("#album_tree [ref=''] .tree-title:first").addClass("ui-selected");
|
||||
};
|
||||
})(jQuery);
|
45
web_client/js/jquery-ui.js
vendored
Normal file
645
web_client/js/jquery.form.js
Normal file
@ -0,0 +1,645 @@
|
||||
/*
|
||||
* jQuery Form Plugin
|
||||
* version: 2.28 (10-MAY-2009)
|
||||
* @requires jQuery v1.2.2 or later
|
||||
*
|
||||
* Examples and documentation at: http://malsup.com/jquery/form/
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
;(function($) {
|
||||
|
||||
/*
|
||||
Usage Note:
|
||||
-----------
|
||||
Do not use both ajaxSubmit and ajaxForm on the same form. These
|
||||
functions are intended to be exclusive. Use ajaxSubmit if you want
|
||||
to bind your own submit handler to the form. For example,
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#myForm').bind('submit', function() {
|
||||
$(this).ajaxSubmit({
|
||||
target: '#output'
|
||||
});
|
||||
return false; // <-- important!
|
||||
});
|
||||
});
|
||||
|
||||
Use ajaxForm when you want the plugin to manage all the event binding
|
||||
for you. For example,
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#myForm').ajaxForm({
|
||||
target: '#output'
|
||||
});
|
||||
});
|
||||
|
||||
When using ajaxForm, the ajaxSubmit function will be invoked for you
|
||||
at the appropriate time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ajaxSubmit() provides a mechanism for immediately submitting
|
||||
* an HTML form using AJAX.
|
||||
*/
|
||||
$.fn.ajaxSubmit = function(options) {
|
||||
// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
|
||||
if (!this.length) {
|
||||
log('ajaxSubmit: skipping submit process - no element selected');
|
||||
return this;
|
||||
}
|
||||
|
||||
if (typeof options == 'function')
|
||||
options = { success: options };
|
||||
|
||||
var url = $.trim(this.attr('action'));
|
||||
if (url) {
|
||||
// clean url (don't include hash vaue)
|
||||
url = (url.match(/^([^#]+)/)||[])[1];
|
||||
}
|
||||
url = url || window.location.href || ''
|
||||
|
||||
options = $.extend({
|
||||
url: url,
|
||||
type: this.attr('method') || 'GET'
|
||||
}, options || {});
|
||||
|
||||
// hook for manipulating the form data before it is extracted;
|
||||
// convenient for use with rich editors like tinyMCE or FCKEditor
|
||||
var veto = {};
|
||||
this.trigger('form-pre-serialize', [this, options, veto]);
|
||||
if (veto.veto) {
|
||||
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
|
||||
return this;
|
||||
}
|
||||
|
||||
// provide opportunity to alter form data before it is serialized
|
||||
if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
|
||||
log('ajaxSubmit: submit aborted via beforeSerialize callback');
|
||||
return this;
|
||||
}
|
||||
|
||||
var a = this.formToArray(options.semantic);
|
||||
if (options.data) {
|
||||
options.extraData = options.data;
|
||||
for (var n in options.data) {
|
||||
if(options.data[n] instanceof Array) {
|
||||
for (var k in options.data[n])
|
||||
a.push( { name: n, value: options.data[n][k] } );
|
||||
}
|
||||
else
|
||||
a.push( { name: n, value: options.data[n] } );
|
||||
}
|
||||
}
|
||||
|
||||
// give pre-submit callback an opportunity to abort the submit
|
||||
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
|
||||
log('ajaxSubmit: submit aborted via beforeSubmit callback');
|
||||
return this;
|
||||
}
|
||||
|
||||
// fire vetoable 'validate' event
|
||||
this.trigger('form-submit-validate', [a, this, options, veto]);
|
||||
if (veto.veto) {
|
||||
log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
|
||||
return this;
|
||||
}
|
||||
|
||||
var q = $.param(a);
|
||||
|
||||
if (options.type.toUpperCase() == 'GET') {
|
||||
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
|
||||
options.data = null; // data is null for 'get'
|
||||
}
|
||||
else
|
||||
options.data = q; // data is the query string for 'post'
|
||||
|
||||
var $form = this, callbacks = [];
|
||||
if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
|
||||
if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
|
||||
|
||||
// perform a load on the target only if dataType is not provided
|
||||
if (!options.dataType && options.target) {
|
||||
var oldSuccess = options.success || function(){};
|
||||
callbacks.push(function(data) {
|
||||
$(options.target).html(data).each(oldSuccess, arguments);
|
||||
});
|
||||
}
|
||||
else if (options.success)
|
||||
callbacks.push(options.success);
|
||||
|
||||
options.success = function(data, status) {
|
||||
for (var i=0, max=callbacks.length; i < max; i++)
|
||||
callbacks[i].apply(options, [data, status, $form]);
|
||||
};
|
||||
|
||||
// are there files to upload?
|
||||
var files = $('input:file', this).fieldValue();
|
||||
var found = false;
|
||||
for (var j=0; j < files.length; j++)
|
||||
if (files[j])
|
||||
found = true;
|
||||
|
||||
var multipart = false;
|
||||
// var mp = 'multipart/form-data';
|
||||
// multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
|
||||
|
||||
// options.iframe allows user to force iframe mode
|
||||
if (options.iframe || found || multipart) {
|
||||
// hack to fix Safari hang (thanks to Tim Molendijk for this)
|
||||
// see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
|
||||
if (options.closeKeepAlive)
|
||||
$.get(options.closeKeepAlive, fileUpload);
|
||||
else
|
||||
fileUpload();
|
||||
}
|
||||
else
|
||||
$.ajax(options);
|
||||
|
||||
// fire 'notify' event
|
||||
this.trigger('form-submit-notify', [this, options]);
|
||||
return this;
|
||||
|
||||
|
||||
// private function for handling file uploads (hat tip to YAHOO!)
|
||||
function fileUpload() {
|
||||
var form = $form[0];
|
||||
|
||||
/* (this breaks the watermark form uploader, turn it off for now)
|
||||
if ($(':input[name=submit]', form).length) {
|
||||
alert('Error: Form elements must not be named "submit".');
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
var opts = $.extend({}, $.ajaxSettings, options);
|
||||
var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
|
||||
|
||||
var id = 'jqFormIO' + (new Date().getTime());
|
||||
var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
|
||||
var io = $io[0];
|
||||
|
||||
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
|
||||
|
||||
var xhr = { // mock object
|
||||
aborted: 0,
|
||||
responseText: null,
|
||||
responseXML: null,
|
||||
status: 0,
|
||||
statusText: 'n/a',
|
||||
getAllResponseHeaders: function() {},
|
||||
getResponseHeader: function() {},
|
||||
setRequestHeader: function() {},
|
||||
abort: function() {
|
||||
this.aborted = 1;
|
||||
$io.attr('src','about:blank'); // abort op in progress
|
||||
}
|
||||
};
|
||||
|
||||
var g = opts.global;
|
||||
// trigger ajax global events so that activity/block indicators work like normal
|
||||
if (g && ! $.active++) $.event.trigger("ajaxStart");
|
||||
if (g) $.event.trigger("ajaxSend", [xhr, opts]);
|
||||
|
||||
if (s.beforeSend && s.beforeSend(xhr, s) === false) {
|
||||
s.global && $.active--;
|
||||
return;
|
||||
}
|
||||
if (xhr.aborted)
|
||||
return;
|
||||
|
||||
var cbInvoked = 0;
|
||||
var timedOut = 0;
|
||||
|
||||
// add submitting element to data if we know it
|
||||
var sub = form.clk;
|
||||
if (sub) {
|
||||
var n = sub.name;
|
||||
if (n && !sub.disabled) {
|
||||
options.extraData = options.extraData || {};
|
||||
options.extraData[n] = sub.value;
|
||||
if (sub.type == "image") {
|
||||
options.extraData[name+'.x'] = form.clk_x;
|
||||
options.extraData[name+'.y'] = form.clk_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take a breath so that pending repaints get some cpu time before the upload starts
|
||||
setTimeout(function() {
|
||||
// make sure form attrs are set
|
||||
var t = $form.attr('target'), a = $form.attr('action');
|
||||
|
||||
// update form attrs in IE friendly way
|
||||
form.setAttribute('target',id);
|
||||
if (form.getAttribute('method') != 'POST')
|
||||
form.setAttribute('method', 'POST');
|
||||
if (form.getAttribute('action') != opts.url)
|
||||
form.setAttribute('action', opts.url);
|
||||
|
||||
// ie borks in some cases when setting encoding
|
||||
if (! options.skipEncodingOverride) {
|
||||
$form.attr({
|
||||
encoding: 'multipart/form-data',
|
||||
enctype: 'multipart/form-data'
|
||||
});
|
||||
}
|
||||
|
||||
// support timout
|
||||
if (opts.timeout)
|
||||
setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
|
||||
|
||||
// add "extra" data to form if provided in options
|
||||
var extraInputs = [];
|
||||
try {
|
||||
if (options.extraData)
|
||||
for (var n in options.extraData)
|
||||
extraInputs.push(
|
||||
$('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
|
||||
.appendTo(form)[0]);
|
||||
|
||||
// add iframe to doc and submit the form
|
||||
$io.appendTo('body');
|
||||
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
|
||||
form.submit();
|
||||
}
|
||||
finally {
|
||||
// reset attrs and remove "extra" input elements
|
||||
form.setAttribute('action',a);
|
||||
t ? form.setAttribute('target', t) : $form.removeAttr('target');
|
||||
$(extraInputs).remove();
|
||||
}
|
||||
}, 10);
|
||||
|
||||
var nullCheckFlag = 0;
|
||||
|
||||
function cb() {
|
||||
if (cbInvoked++) return;
|
||||
|
||||
io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
|
||||
|
||||
var ok = true;
|
||||
try {
|
||||
if (timedOut) throw 'timeout';
|
||||
// extract the server response from the iframe
|
||||
var data, doc;
|
||||
|
||||
doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
|
||||
|
||||
if ((doc.body == null || doc.body.innerHTML == '') && !nullCheckFlag) {
|
||||
// in some browsers (cough, Opera 9.2.x) the iframe DOM is not always traversable when
|
||||
// the onload callback fires, so we give them a 2nd chance
|
||||
nullCheckFlag = 1;
|
||||
cbInvoked--;
|
||||
setTimeout(cb, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
xhr.responseText = doc.body ? doc.body.innerHTML : null;
|
||||
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
|
||||
xhr.getResponseHeader = function(header){
|
||||
var headers = {'content-type': opts.dataType};
|
||||
return headers[header];
|
||||
};
|
||||
|
||||
if (opts.dataType == 'json' || opts.dataType == 'script') {
|
||||
var ta = doc.getElementsByTagName('textarea')[0];
|
||||
xhr.responseText = ta ? ta.value : xhr.responseText;
|
||||
}
|
||||
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
|
||||
xhr.responseXML = toXml(xhr.responseText);
|
||||
}
|
||||
data = $.httpData(xhr, opts.dataType);
|
||||
}
|
||||
catch(e){
|
||||
ok = false;
|
||||
$.handleError(opts, xhr, 'error', e);
|
||||
}
|
||||
|
||||
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
|
||||
if (ok) {
|
||||
opts.success(data, 'success');
|
||||
if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
|
||||
}
|
||||
if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
|
||||
if (g && ! --$.active) $.event.trigger("ajaxStop");
|
||||
if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
|
||||
|
||||
// clean up
|
||||
setTimeout(function() {
|
||||
$io.remove();
|
||||
xhr.responseXML = null;
|
||||
}, 100);
|
||||
};
|
||||
|
||||
function toXml(s, doc) {
|
||||
if (window.ActiveXObject) {
|
||||
doc = new ActiveXObject('Microsoft.XMLDOM');
|
||||
doc.async = 'false';
|
||||
doc.loadXML(s);
|
||||
}
|
||||
else
|
||||
doc = (new DOMParser()).parseFromString(s, 'text/xml');
|
||||
return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* ajaxForm() provides a mechanism for fully automating form submission.
|
||||
*
|
||||
* The advantages of using this method instead of ajaxSubmit() are:
|
||||
*
|
||||
* 1: This method will include coordinates for <input type="image" /> elements (if the element
|
||||
* is used to submit the form).
|
||||
* 2. This method will include the submit element's name/value data (for the element that was
|
||||
* used to submit the form).
|
||||
* 3. This method binds the submit() method to the form for you.
|
||||
*
|
||||
* The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
|
||||
* passes the options argument along after properly binding events for submit elements and
|
||||
* the form itself.
|
||||
*/
|
||||
$.fn.ajaxForm = function(options) {
|
||||
return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
|
||||
$(this).ajaxSubmit(options);
|
||||
return false;
|
||||
}).each(function() {
|
||||
// store options in hash
|
||||
$(":submit,input:image", this).bind('click.form-plugin',function(e) {
|
||||
var form = this.form;
|
||||
form.clk = this;
|
||||
if (this.type == 'image') {
|
||||
if (e.offsetX != undefined) {
|
||||
form.clk_x = e.offsetX;
|
||||
form.clk_y = e.offsetY;
|
||||
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
|
||||
var offset = $(this).offset();
|
||||
form.clk_x = e.pageX - offset.left;
|
||||
form.clk_y = e.pageY - offset.top;
|
||||
} else {
|
||||
form.clk_x = e.pageX - this.offsetLeft;
|
||||
form.clk_y = e.pageY - this.offsetTop;
|
||||
}
|
||||
}
|
||||
// clear form vars
|
||||
setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
|
||||
$.fn.ajaxFormUnbind = function() {
|
||||
this.unbind('submit.form-plugin');
|
||||
return this.each(function() {
|
||||
$(":submit,input:image", this).unbind('click.form-plugin');
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* formToArray() gathers form element data into an array of objects that can
|
||||
* be passed to any of the following ajax functions: $.get, $.post, or load.
|
||||
* Each object in the array has both a 'name' and 'value' property. An example of
|
||||
* an array for a simple login form might be:
|
||||
*
|
||||
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
|
||||
*
|
||||
* It is this array that is passed to pre-submit callback functions provided to the
|
||||
* ajaxSubmit() and ajaxForm() methods.
|
||||
*/
|
||||
$.fn.formToArray = function(semantic) {
|
||||
var a = [];
|
||||
if (this.length == 0) return a;
|
||||
|
||||
var form = this[0];
|
||||
var els = semantic ? form.getElementsByTagName('*') : form.elements;
|
||||
if (!els) return a;
|
||||
for(var i=0, max=els.length; i < max; i++) {
|
||||
var el = els[i];
|
||||
var n = el.name;
|
||||
if (!n) continue;
|
||||
|
||||
if (semantic && form.clk && el.type == "image") {
|
||||
// handle image inputs on the fly when semantic == true
|
||||
if(!el.disabled && form.clk == el) {
|
||||
a.push({name: n, value: $(el).val()});
|
||||
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var v = $.fieldValue(el, true);
|
||||
if (v && v.constructor == Array) {
|
||||
for(var j=0, jmax=v.length; j < jmax; j++)
|
||||
a.push({name: n, value: v[j]});
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined')
|
||||
a.push({name: n, value: v});
|
||||
}
|
||||
|
||||
if (!semantic && form.clk) {
|
||||
// input type=='image' are not found in elements array! handle it here
|
||||
var $input = $(form.clk), input = $input[0], n = input.name;
|
||||
if (n && !input.disabled && input.type == 'image') {
|
||||
a.push({name: n, value: $input.val()});
|
||||
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes form data into a 'submittable' string. This method will return a string
|
||||
* in the format: name1=value1&name2=value2
|
||||
*/
|
||||
$.fn.formSerialize = function(semantic) {
|
||||
//hand off to jQuery.param for proper encoding
|
||||
return $.param(this.formToArray(semantic));
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes all field elements in the jQuery object into a query string.
|
||||
* This method will return a string in the format: name1=value1&name2=value2
|
||||
*/
|
||||
$.fn.fieldSerialize = function(successful) {
|
||||
var a = [];
|
||||
this.each(function() {
|
||||
var n = this.name;
|
||||
if (!n) return;
|
||||
var v = $.fieldValue(this, successful);
|
||||
if (v && v.constructor == Array) {
|
||||
for (var i=0,max=v.length; i < max; i++)
|
||||
a.push({name: n, value: v[i]});
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined')
|
||||
a.push({name: this.name, value: v});
|
||||
});
|
||||
//hand off to jQuery.param for proper encoding
|
||||
return $.param(a);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value(s) of the element in the matched set. For example, consider the following form:
|
||||
*
|
||||
* <form><fieldset>
|
||||
* <input name="A" type="text" />
|
||||
* <input name="A" type="text" />
|
||||
* <input name="B" type="checkbox" value="B1" />
|
||||
* <input name="B" type="checkbox" value="B2"/>
|
||||
* <input name="C" type="radio" value="C1" />
|
||||
* <input name="C" type="radio" value="C2" />
|
||||
* </fieldset></form>
|
||||
*
|
||||
* var v = $(':text').fieldValue();
|
||||
* // if no values are entered into the text inputs
|
||||
* v == ['','']
|
||||
* // if values entered into the text inputs are 'foo' and 'bar'
|
||||
* v == ['foo','bar']
|
||||
*
|
||||
* var v = $(':checkbox').fieldValue();
|
||||
* // if neither checkbox is checked
|
||||
* v === undefined
|
||||
* // if both checkboxes are checked
|
||||
* v == ['B1', 'B2']
|
||||
*
|
||||
* var v = $(':radio').fieldValue();
|
||||
* // if neither radio is checked
|
||||
* v === undefined
|
||||
* // if first radio is checked
|
||||
* v == ['C1']
|
||||
*
|
||||
* The successful argument controls whether or not the field element must be 'successful'
|
||||
* (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
|
||||
* The default value of the successful argument is true. If this value is false the value(s)
|
||||
* for each element is returned.
|
||||
*
|
||||
* Note: This method *always* returns an array. If no valid value can be determined the
|
||||
* array will be empty, otherwise it will contain one or more values.
|
||||
*/
|
||||
$.fn.fieldValue = function(successful) {
|
||||
for (var val=[], i=0, max=this.length; i < max; i++) {
|
||||
var el = this[i];
|
||||
var v = $.fieldValue(el, successful);
|
||||
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
|
||||
continue;
|
||||
v.constructor == Array ? $.merge(val, v) : val.push(v);
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value of the field element.
|
||||
*/
|
||||
$.fieldValue = function(el, successful) {
|
||||
var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
|
||||
if (typeof successful == 'undefined') successful = true;
|
||||
|
||||
if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
|
||||
(t == 'checkbox' || t == 'radio') && !el.checked ||
|
||||
(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
|
||||
tag == 'select' && el.selectedIndex == -1))
|
||||
return null;
|
||||
|
||||
if (tag == 'select') {
|
||||
var index = el.selectedIndex;
|
||||
if (index < 0) return null;
|
||||
var a = [], ops = el.options;
|
||||
var one = (t == 'select-one');
|
||||
var max = (one ? index+1 : ops.length);
|
||||
for(var i=(one ? index : 0); i < max; i++) {
|
||||
var op = ops[i];
|
||||
if (op.selected) {
|
||||
var v = op.value;
|
||||
if (!v) // extra pain for IE...
|
||||
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
|
||||
if (one) return v;
|
||||
a.push(v);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return el.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the form data. Takes the following actions on the form's input fields:
|
||||
* - input text fields will have their 'value' property set to the empty string
|
||||
* - select elements will have their 'selectedIndex' property set to -1
|
||||
* - checkbox and radio inputs will have their 'checked' property set to false
|
||||
* - inputs of type submit, button, reset, and hidden will *not* be effected
|
||||
* - button elements will *not* be effected
|
||||
*/
|
||||
$.fn.clearForm = function() {
|
||||
return this.each(function() {
|
||||
$('input,select,textarea', this).clearFields();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the selected form elements.
|
||||
*/
|
||||
$.fn.clearFields = $.fn.clearInputs = function() {
|
||||
return this.each(function() {
|
||||
var t = this.type, tag = this.tagName.toLowerCase();
|
||||
if (t == 'text' || t == 'password' || tag == 'textarea')
|
||||
this.value = '';
|
||||
else if (t == 'checkbox' || t == 'radio')
|
||||
this.checked = false;
|
||||
else if (tag == 'select')
|
||||
this.selectedIndex = -1;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the form data. Causes all form elements to be reset to their original value.
|
||||
*/
|
||||
$.fn.resetForm = function() {
|
||||
return this.each(function() {
|
||||
// guard against an input with the name of 'reset'
|
||||
// note that IE reports the reset function as an 'object'
|
||||
if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
|
||||
this.reset();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables any matching elements.
|
||||
*/
|
||||
$.fn.enable = function(b) {
|
||||
if (b == undefined) b = true;
|
||||
return this.each(function() {
|
||||
this.disabled = !b;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks/unchecks any matching checkboxes or radio buttons and
|
||||
* selects/deselects and matching option elements.
|
||||
*/
|
||||
$.fn.selected = function(select) {
|
||||
if (select == undefined) select = true;
|
||||
return this.each(function() {
|
||||
var t = this.type;
|
||||
if (t == 'checkbox' || t == 'radio')
|
||||
this.checked = select;
|
||||
else if (this.tagName.toLowerCase() == 'option') {
|
||||
var $sel = $(this).parent('select');
|
||||
if (select && $sel[0] && $sel[0].type == 'select-one') {
|
||||
// deselect all other options
|
||||
$sel.find('option').selected(false);
|
||||
}
|
||||
this.selected = select;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// helper fn for console logging
|
||||
// set $.fn.ajaxSubmit.debug to true to enable debug logging
|
||||
function log() {
|
||||
if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
|
||||
window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
|
||||
};
|
||||
|
||||
})(jQuery);
|
19
web_client/js/jquery.js
vendored
Normal file
BIN
web_client/kohana.png
Normal file
After Width: | Height: | Size: 23 KiB |
31
web_client/system/config/cache.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Cache
|
||||
*
|
||||
* Cache settings, defined as arrays, or "groups". If no group name is
|
||||
* used when loading the cache library, the group named "default" will be used.
|
||||
*
|
||||
* Each group can be used independently, and multiple groups can be used at once.
|
||||
*
|
||||
* Group Options:
|
||||
* driver - Cache backend driver. Kohana comes with file, database, and memcache drivers.
|
||||
* > File cache is fast and reliable, but requires many filesystem lookups.
|
||||
* > Database cache can be used to cache items remotely, but is slower.
|
||||
* > Memcache is very high performance, but prevents cache tags from being used.
|
||||
*
|
||||
* params - Driver parameters, specific to each driver.
|
||||
*
|
||||
* lifetime - Default lifetime of caches in seconds. By default caches are stored for
|
||||
* thirty minutes. Specific lifetime can also be set when creating a new cache.
|
||||
* Setting this to 0 will never automatically delete caches.
|
||||
*
|
||||
* prefix - Adds a prefix to all keys and tags. This can have a severe performance impact.
|
||||
*
|
||||
*/
|
||||
$config['default'] = array
|
||||
(
|
||||
'driver' => 'file',
|
||||
'params' => array('directory' => APPPATH.'cache', 'gc_probability' => 1000),
|
||||
'lifetime' => 1800,
|
||||
'prefix' => NULL
|
||||
);
|
38
web_client/system/config/cookie.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* Domain, to restrict the cookie to a specific website domain. For security,
|
||||
* you are encouraged to set this option. An empty setting allows the cookie
|
||||
* to be read by any website domain.
|
||||
*/
|
||||
$config['domain'] = '';
|
||||
|
||||
/**
|
||||
* Restrict cookies to a specific path, typically the installation directory.
|
||||
*/
|
||||
$config['path'] = '/';
|
||||
|
||||
/**
|
||||
* Lifetime of the cookie. A setting of 0 makes the cookie active until the
|
||||
* users browser is closed or the cookie is deleted.
|
||||
*/
|
||||
$config['expire'] = 0;
|
||||
|
||||
/**
|
||||
* Enable this option to only allow the cookie to be read when using the a
|
||||
* secure protocol.
|
||||
*/
|
||||
$config['secure'] = FALSE;
|
||||
|
||||
/**
|
||||
* Enable this option to make the cookie accessible only through the
|
||||
* HTTP protocol (e.g. no javascript access). This is not supported by all browsers.
|
||||
*/
|
||||
$config['httponly'] = FALSE;
|
||||
|
||||
/**
|
||||
* Cookie salt for signed cookies.
|
||||
* Make sure you change this to a unique value.
|
||||
*/
|
||||
$config['salt'] = 'K0hAN4 15 Th3 B357';
|
60
web_client/system/config/credit_cards.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Credit card validation configuration.
|
||||
*
|
||||
* Options for each credit card:
|
||||
* length - All the allowed card number lengths, in a comma separated string
|
||||
* prefix - The digits the card needs to start with, in regex format
|
||||
* luhn - Enable or disable card number validation by the Luhn algorithm
|
||||
*/
|
||||
$config = array
|
||||
(
|
||||
'default' => array
|
||||
(
|
||||
'length' => '13,14,15,16,17,18,19',
|
||||
'prefix' => '',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'american express' => array
|
||||
(
|
||||
'length' => '15',
|
||||
'prefix' => '3[47]',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'diners club' => array
|
||||
(
|
||||
'length' => '14,16',
|
||||
'prefix' => '36|55|30[0-5]',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'discover' => array
|
||||
(
|
||||
'length' => '16',
|
||||
'prefix' => '6(?:5|011)',
|
||||
'luhn' => TRUE,
|
||||
),
|
||||
'jcb' => array
|
||||
(
|
||||
'length' => '15,16',
|
||||
'prefix' => '3|1800|2131',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'maestro' => array
|
||||
(
|
||||
'length' => '16,18',
|
||||
'prefix' => '50(?:20|38)|6(?:304|759)',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'mastercard' => array
|
||||
(
|
||||
'length' => '16',
|
||||
'prefix' => '5[1-5]',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
'visa' => array
|
||||
(
|
||||
'length' => '13,16',
|
||||
'prefix' => '4',
|
||||
'luhn' => TRUE
|
||||
),
|
||||
);
|
46
web_client/system/config/database.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Database
|
||||
*
|
||||
* Database connection settings, defined as arrays, or "groups". If no group
|
||||
* name is used when loading the database library, the group named "default"
|
||||
* will be used.
|
||||
*
|
||||
* Each group can be connected to independently, and multiple groups can be
|
||||
* connected at once.
|
||||
*
|
||||
* Group Options:
|
||||
* benchmark - Enable or disable database benchmarking
|
||||
* persistent - Enable or disable a persistent connection
|
||||
* connection - Array of connection specific parameters; alternatively,
|
||||
* you can use a DSN though it is not as fast and certain
|
||||
* characters could create problems (like an '@' character
|
||||
* in a password):
|
||||
* 'connection' => 'mysql://dbuser:secret@localhost/kohana'
|
||||
* character_set - Database character set
|
||||
* table_prefix - Database table prefix
|
||||
* object - Enable or disable object results
|
||||
* cache - Enable or disable query caching
|
||||
* escape - Enable automatic query builder escaping
|
||||
*/
|
||||
$config['default'] = array
|
||||
(
|
||||
'benchmark' => FALSE,
|
||||
'persistent' => FALSE,
|
||||
'connection' => array
|
||||
(
|
||||
'type' => 'mysql',
|
||||
'user' => 'dbuser',
|
||||
'pass' => 'p@ssw0rd',
|
||||
'host' => 'localhost',
|
||||
'port' => FALSE,
|
||||
'socket' => FALSE,
|
||||
'database' => 'kohana',
|
||||
'params' => NULL,
|
||||
),
|
||||
'character_set' => 'utf8',
|
||||
'table_prefix' => '',
|
||||
'object' => TRUE,
|
||||
'cache' => FALSE,
|
||||
'escape' => TRUE
|
||||
);
|
31
web_client/system/config/encryption.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Encrypt
|
||||
*
|
||||
* Encrypt configuration is defined in groups which allows you to easily switch
|
||||
* between different encryption settings for different uses.
|
||||
* Note: all groups inherit and overwrite the default group.
|
||||
*
|
||||
* Group Options:
|
||||
* key - Encryption key used to do encryption and decryption. The default option
|
||||
* should never be used for a production website.
|
||||
*
|
||||
* For best security, your encryption key should be at least 16 characters
|
||||
* long and contain letters, numbers, and symbols.
|
||||
* @note Do not use a hash as your key. This significantly lowers encryption entropy.
|
||||
*
|
||||
* mode - MCrypt encryption mode. By default, MCRYPT_MODE_NOFB is used. This mode
|
||||
* offers initialization vector support, is suited to short strings, and
|
||||
* produces the shortest encrypted output.
|
||||
* @see http://php.net/mcrypt
|
||||
*
|
||||
* cipher - MCrypt encryption cipher. By default, the MCRYPT_RIJNDAEL_128 cipher is used.
|
||||
* This is also known as 128-bit AES.
|
||||
* @see http://php.net/mcrypt
|
||||
*/
|
||||
$config['default'] = array
|
||||
(
|
||||
'key' => 'K0H@NA+PHP_7hE-SW!FtFraM3w0R|<',
|
||||
'mode' => MCRYPT_MODE_NOFB,
|
||||
'cipher' => MCRYPT_RIJNDAEL_128
|
||||
);
|
7
web_client/system/config/html_purifier.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* If using HTMLPurifier then this option allows setting an
|
||||
* alternative path for the cache data. Note that that path
|
||||
* must be an absolute location.
|
||||
*/
|
||||
$config['cache'] = '/tmp/htmlpurifier';
|
19
web_client/system/config/http.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
// HTTP-EQUIV type meta tags
|
||||
$config['meta_equiv'] = array
|
||||
(
|
||||
'cache-control',
|
||||
'content-type', 'content-script-type', 'content-style-type',
|
||||
'content-disposition',
|
||||
'content-language',
|
||||
'default-style',
|
||||
'expires',
|
||||
'ext-cache',
|
||||
'pics-label',
|
||||
'pragma',
|
||||
'refresh',
|
||||
'set-cookie',
|
||||
'vary',
|
||||
'window-target',
|
||||
);
|
13
web_client/system/config/image.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Image
|
||||
*
|
||||
* Driver name. Default: GD
|
||||
*/
|
||||
$config['driver'] = 'GD';
|
||||
|
||||
/**
|
||||
* Driver parameters:
|
||||
* ImageMagick - set the "directory" parameter to your ImageMagick installation directory
|
||||
*/
|
||||
$config['params'] = array();
|
60
web_client/system/config/inflector.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
$config['uncountable'] = array
|
||||
(
|
||||
'access',
|
||||
'advice',
|
||||
'art',
|
||||
'baggage',
|
||||
'dances',
|
||||
'data',
|
||||
'equipment',
|
||||
'fish',
|
||||
'fuel',
|
||||
'furniture',
|
||||
'food',
|
||||
'heat',
|
||||
'honey',
|
||||
'homework',
|
||||
'impatience',
|
||||
'information',
|
||||
'knowledge',
|
||||
'luggage',
|
||||
'metadata',
|
||||
'money',
|
||||
'music',
|
||||
'news',
|
||||
'patience',
|
||||
'progress',
|
||||
'pollution',
|
||||
'research',
|
||||
'rice',
|
||||
'sand',
|
||||
'series',
|
||||
'sheep',
|
||||
'sms',
|
||||
'species',
|
||||
'staff',
|
||||
'toothpaste',
|
||||
'traffic',
|
||||
'understanding',
|
||||
'water',
|
||||
'weather',
|
||||
'work',
|
||||
);
|
||||
|
||||
$config['irregular'] = array
|
||||
(
|
||||
'child' => 'children',
|
||||
'clothes' => 'clothing',
|
||||
'man' => 'men',
|
||||
'movie' => 'movies',
|
||||
'person' => 'people',
|
||||
'woman' => 'women',
|
||||
'mouse' => 'mice',
|
||||
'goose' => 'geese',
|
||||
'ox' => 'oxen',
|
||||
'leaf' => 'leaves',
|
||||
'course' => 'courses',
|
||||
'size' => 'sizes',
|
||||
);
|
17
web_client/system/config/locale.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* Default language locale name(s).
|
||||
* First item must be a valid i18n directory name, subsequent items are alternative locales
|
||||
* for OS's that don't support the first (e.g. Windows). The first valid locale in the array will be used.
|
||||
* @see http://php.net/setlocale
|
||||
*/
|
||||
$config['language'] = array('en_US', 'English_United States');
|
||||
|
||||
/**
|
||||
* Locale timezone. Defaults to the timezone you have set in your php config
|
||||
* This cannot be left empty, a valid timezone is required!
|
||||
* @see http://php.net/timezones
|
||||
*/
|
||||
$config['timezone'] = ini_get('date.timezone');
|
19
web_client/system/config/log.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
|
||||
// Different log levels
|
||||
$config['log_levels'] = array
|
||||
(
|
||||
'error' => 1,
|
||||
'alert' => 2,
|
||||
'info' => 3,
|
||||
'debug' => 4,
|
||||
);
|
||||
|
||||
// See different log levels above
|
||||
$config['log_threshold'] = 1;
|
||||
|
||||
$config['date_format'] = 'Y-m-d H:i:s P';
|
||||
|
||||
// We can define multiple logging backends at the same time.
|
||||
$config['drivers'] = array('file');
|
24
web_client/system/config/log_database.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* Database config group to store log messages
|
||||
*/
|
||||
$config['group'] = 'default';
|
||||
|
||||
/**
|
||||
* Database table to store log messages in
|
||||
*/
|
||||
$config['table'] = 'logs';
|
||||
|
||||
/* MySQL Database schema:
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `logs` (
|
||||
`id` int(10) unsigned NOT NULL auto_increment,
|
||||
`date` int(11) NOT NULL,
|
||||
`level` varchar(5) NOT NULL,
|
||||
`message` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `date` (`date`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
|
||||
|
||||
*/
|
11
web_client/system/config/log_file.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* Message logging directory.
|
||||
*/
|
||||
$config['log_directory'] = APPPATH.'logs';
|
||||
|
||||
/**
|
||||
* Permissions of the log file
|
||||
*/
|
||||
$config['posix_permissions'] = 0644;
|
6
web_client/system/config/log_syslog.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* Ident string added to each syslog message
|
||||
*/
|
||||
$config['ident'] = 'KohanaPHP';
|
224
web_client/system/config/mimes.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* A list of mime types. Our list is generally more complete and accurate than
|
||||
* the operating system MIME list.
|
||||
*
|
||||
* If there are any missing options, please create a ticket on our issue tracker,
|
||||
* http://dev.kohanaphp.com/projects/kohana2. Be sure to give the filename and
|
||||
* expected MIME type, as well as any additional information you can provide.
|
||||
*/
|
||||
$config = array
|
||||
(
|
||||
'323' => array('text/h323'),
|
||||
'7z' => array('application/x-7z-compressed'),
|
||||
'abw' => array('application/x-abiword'),
|
||||
'acx' => array('application/internet-property-stream'),
|
||||
'ai' => array('application/postscript'),
|
||||
'aif' => array('audio/x-aiff'),
|
||||
'aifc' => array('audio/x-aiff'),
|
||||
'aiff' => array('audio/x-aiff'),
|
||||
'asf' => array('video/x-ms-asf'),
|
||||
'asr' => array('video/x-ms-asf'),
|
||||
'asx' => array('video/x-ms-asf'),
|
||||
'atom' => array('application/atom+xml'),
|
||||
'avi' => array('video/avi', 'video/msvideo', 'video/x-msvideo'),
|
||||
'bin' => array('application/octet-stream','application/macbinary'),
|
||||
'bmp' => array('image/bmp'),
|
||||
'c' => array('text/x-csrc'),
|
||||
'c++' => array('text/x-c++src'),
|
||||
'cab' => array('application/x-cab'),
|
||||
'cc' => array('text/x-c++src'),
|
||||
'cda' => array('application/x-cdf'),
|
||||
'class' => array('application/octet-stream'),
|
||||
'cpp' => array('text/x-c++src'),
|
||||
'cpt' => array('application/mac-compactpro'),
|
||||
'csh' => array('text/x-csh'),
|
||||
'css' => array('text/css'),
|
||||
'csv' => array('text/x-comma-separated-values', 'application/vnd.ms-excel', 'text/comma-separated-values', 'text/csv'),
|
||||
'dbk' => array('application/docbook+xml'),
|
||||
'dcr' => array('application/x-director'),
|
||||
'deb' => array('application/x-debian-package'),
|
||||
'diff' => array('text/x-diff'),
|
||||
'dir' => array('application/x-director'),
|
||||
'divx' => array('video/divx'),
|
||||
'dll' => array('application/octet-stream', 'application/x-msdos-program'),
|
||||
'dmg' => array('application/x-apple-diskimage'),
|
||||
'dms' => array('application/octet-stream'),
|
||||
'doc' => array('application/msword'),
|
||||
'dvi' => array('application/x-dvi'),
|
||||
'dxr' => array('application/x-director'),
|
||||
'eml' => array('message/rfc822'),
|
||||
'eps' => array('application/postscript'),
|
||||
'evy' => array('application/envoy'),
|
||||
'exe' => array('application/x-msdos-program', 'application/octet-stream'),
|
||||
'fla' => array('application/octet-stream'),
|
||||
'flac' => array('application/x-flac'),
|
||||
'flc' => array('video/flc'),
|
||||
'fli' => array('video/fli'),
|
||||
'flv' => array('video/x-flv'),
|
||||
'gif' => array('image/gif'),
|
||||
'gtar' => array('application/x-gtar'),
|
||||
'gz' => array('application/x-gzip'),
|
||||
'h' => array('text/x-chdr'),
|
||||
'h++' => array('text/x-c++hdr'),
|
||||
'hh' => array('text/x-c++hdr'),
|
||||
'hpp' => array('text/x-c++hdr'),
|
||||
'hqx' => array('application/mac-binhex40'),
|
||||
'hs' => array('text/x-haskell'),
|
||||
'htm' => array('text/html'),
|
||||
'html' => array('text/html'),
|
||||
'ico' => array('image/x-icon'),
|
||||
'ics' => array('text/calendar'),
|
||||
'iii' => array('application/x-iphone'),
|
||||
'ins' => array('application/x-internet-signup'),
|
||||
'iso' => array('application/x-iso9660-image'),
|
||||
'isp' => array('application/x-internet-signup'),
|
||||
'jar' => array('application/java-archive'),
|
||||
'java' => array('application/x-java-applet'),
|
||||
'jpe' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpeg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'js' => array('application/x-javascript'),
|
||||
'json' => array('application/json'),
|
||||
'latex' => array('application/x-latex'),
|
||||
'lha' => array('application/octet-stream'),
|
||||
'log' => array('text/plain', 'text/x-log'),
|
||||
'lzh' => array('application/octet-stream'),
|
||||
'm4a' => array('audio/mpeg'),
|
||||
'm4p' => array('video/mp4v-es'),
|
||||
'm4v' => array('video/mp4'),
|
||||
'man' => array('application/x-troff-man'),
|
||||
'mdb' => array('application/x-msaccess'),
|
||||
'midi' => array('audio/midi'),
|
||||
'mid' => array('audio/midi'),
|
||||
'mif' => array('application/vnd.mif'),
|
||||
'mka' => array('audio/x-matroska'),
|
||||
'mkv' => array('video/x-matroska'),
|
||||
'mov' => array('video/quicktime'),
|
||||
'movie' => array('video/x-sgi-movie'),
|
||||
'mp2' => array('audio/mpeg'),
|
||||
'mp3' => array('audio/mpeg'),
|
||||
'mp4' => array('application/mp4','audio/mp4','video/mp4'),
|
||||
'mpa' => array('video/mpeg'),
|
||||
'mpe' => array('video/mpeg'),
|
||||
'mpeg' => array('video/mpeg'),
|
||||
'mpg' => array('video/mpeg'),
|
||||
'mpg4' => array('video/mp4'),
|
||||
'mpga' => array('audio/mpeg'),
|
||||
'mpp' => array('application/vnd.ms-project'),
|
||||
'mpv' => array('video/x-matroska'),
|
||||
'mpv2' => array('video/mpeg'),
|
||||
'ms' => array('application/x-troff-ms'),
|
||||
'msg' => array('application/msoutlook','application/x-msg'),
|
||||
'msi' => array('application/x-msi'),
|
||||
'nws' => array('message/rfc822'),
|
||||
'oda' => array('application/oda'),
|
||||
'odb' => array('application/vnd.oasis.opendocument.database'),
|
||||
'odc' => array('application/vnd.oasis.opendocument.chart'),
|
||||
'odf' => array('application/vnd.oasis.opendocument.forumla'),
|
||||
'odg' => array('application/vnd.oasis.opendocument.graphics'),
|
||||
'odi' => array('application/vnd.oasis.opendocument.image'),
|
||||
'odm' => array('application/vnd.oasis.opendocument.text-master'),
|
||||
'odp' => array('application/vnd.oasis.opendocument.presentation'),
|
||||
'ods' => array('application/vnd.oasis.opendocument.spreadsheet'),
|
||||
'odt' => array('application/vnd.oasis.opendocument.text'),
|
||||
'oga' => array('audio/ogg'),
|
||||
'ogg' => array('application/ogg'),
|
||||
'ogv' => array('video/ogg'),
|
||||
'otg' => array('application/vnd.oasis.opendocument.graphics-template'),
|
||||
'oth' => array('application/vnd.oasis.opendocument.web'),
|
||||
'otp' => array('application/vnd.oasis.opendocument.presentation-template'),
|
||||
'ots' => array('application/vnd.oasis.opendocument.spreadsheet-template'),
|
||||
'ott' => array('application/vnd.oasis.opendocument.template'),
|
||||
'p' => array('text/x-pascal'),
|
||||
'pas' => array('text/x-pascal'),
|
||||
'patch' => array('text/x-diff'),
|
||||
'pbm' => array('image/x-portable-bitmap'),
|
||||
'pdf' => array('application/pdf', 'application/x-download'),
|
||||
'php' => array('application/x-httpd-php'),
|
||||
'php3' => array('application/x-httpd-php'),
|
||||
'php4' => array('application/x-httpd-php'),
|
||||
'php5' => array('application/x-httpd-php'),
|
||||
'phps' => array('application/x-httpd-php-source'),
|
||||
'phtml' => array('application/x-httpd-php'),
|
||||
'pl' => array('text/x-perl'),
|
||||
'pm' => array('text/x-perl'),
|
||||
'png' => array('image/png', 'image/x-png'),
|
||||
'po' => array('text/x-gettext-translation'),
|
||||
'pot' => array('application/vnd.ms-powerpoint'),
|
||||
'pps' => array('application/vnd.ms-powerpoint'),
|
||||
'ppt' => array('application/powerpoint'),
|
||||
'ps' => array('application/postscript'),
|
||||
'psd' => array('application/x-photoshop', 'image/x-photoshop'),
|
||||
'pub' => array('application/x-mspublisher'),
|
||||
'py' => array('text/x-python'),
|
||||
'qt' => array('video/quicktime'),
|
||||
'ra' => array('audio/x-realaudio'),
|
||||
'ram' => array('audio/x-realaudio', 'audio/x-pn-realaudio'),
|
||||
'rar' => array('application/rar'),
|
||||
'rgb' => array('image/x-rgb'),
|
||||
'rm' => array('audio/x-pn-realaudio'),
|
||||
'rpm' => array('audio/x-pn-realaudio-plugin', 'application/x-redhat-package-manager'),
|
||||
'rss' => array('application/rss+xml'),
|
||||
'rtf' => array('text/rtf'),
|
||||
'rtx' => array('text/richtext'),
|
||||
'rv' => array('video/vnd.rn-realvideo'),
|
||||
'sea' => array('application/octet-stream'),
|
||||
'sh' => array('text/x-sh'),
|
||||
'shtml' => array('text/html'),
|
||||
'sit' => array('application/x-stuffit'),
|
||||
'smi' => array('application/smil'),
|
||||
'smil' => array('application/smil'),
|
||||
'so' => array('application/octet-stream'),
|
||||
'src' => array('application/x-wais-source'),
|
||||
'svg' => array('image/svg+xml'),
|
||||
'swf' => array('application/x-shockwave-flash'),
|
||||
't' => array('application/x-troff'),
|
||||
'tar' => array('application/x-tar'),
|
||||
'tcl' => array('text/x-tcl'),
|
||||
'tex' => array('application/x-tex'),
|
||||
'text' => array('text/plain'),
|
||||
'texti' => array('application/x-texinfo'),
|
||||
'textinfo' => array('application/x-texinfo'),
|
||||
'tgz' => array('application/x-tar'),
|
||||
'tif' => array('image/tiff'),
|
||||
'tiff' => array('image/tiff'),
|
||||
'torrent' => array('application/x-bittorrent'),
|
||||
'tr' => array('application/x-troff'),
|
||||
'tsv' => array('text/tab-separated-values'),
|
||||
'txt' => array('text/plain'),
|
||||
'wav' => array('audio/x-wav'),
|
||||
'wax' => array('audio/x-ms-wax'),
|
||||
'wbxml' => array('application/wbxml'),
|
||||
'wm' => array('video/x-ms-wm'),
|
||||
'wma' => array('audio/x-ms-wma'),
|
||||
'wmd' => array('application/x-ms-wmd'),
|
||||
'wmlc' => array('application/wmlc'),
|
||||
'wmv' => array('video/x-ms-wmv', 'application/octet-stream'),
|
||||
'wmx' => array('video/x-ms-wmx'),
|
||||
'wmz' => array('application/x-ms-wmz'),
|
||||
'word' => array('application/msword', 'application/octet-stream'),
|
||||
'wp5' => array('application/wordperfect5.1'),
|
||||
'wpd' => array('application/vnd.wordperfect'),
|
||||
'wvx' => array('video/x-ms-wvx'),
|
||||
'xbm' => array('image/x-xbitmap'),
|
||||
'xcf' => array('image/xcf'),
|
||||
'xhtml' => array('application/xhtml+xml'),
|
||||
'xht' => array('application/xhtml+xml'),
|
||||
'xl' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xla' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xlc' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xlm' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xls' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xlt' => array('application/excel', 'application/vnd.ms-excel'),
|
||||
'xml' => array('text/xml'),
|
||||
'xof' => array('x-world/x-vrml'),
|
||||
'xpm' => array('image/x-xpixmap'),
|
||||
'xsl' => array('text/xml'),
|
||||
'xvid' => array('video/x-xvid'),
|
||||
'xwd' => array('image/x-xwindowdump'),
|
||||
'z' => array('application/x-compress'),
|
||||
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed')
|
||||
);
|
12
web_client/system/config/profiler.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Profiler
|
||||
*
|
||||
* Array of section names to display in the Profiler, TRUE to display all of them.
|
||||
* Built in sections are benchmarks, database, session, post and cookies, custom sections can be used too.
|
||||
*/
|
||||
$config['show'] = TRUE;
|
||||
|
||||
$config['time_decimals'] = 3;
|
||||
|
||||
$config['memory_decimals'] = 2;
|
7
web_client/system/config/routes.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* Sets the default route to "welcome"
|
||||
*/
|
||||
$config['_default'] = 'welcome';
|
48
web_client/system/config/session.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Session
|
||||
*
|
||||
* Session driver name.
|
||||
*/
|
||||
$config['driver'] = 'cookie';
|
||||
|
||||
/**
|
||||
* Session storage parameter, used by drivers.
|
||||
*/
|
||||
$config['storage'] = '';
|
||||
|
||||
/**
|
||||
* Session name.
|
||||
* It must contain only alphanumeric characters and underscores. At least one letter must be present.
|
||||
*/
|
||||
$config['name'] = 'kohanasession';
|
||||
|
||||
/**
|
||||
* Session parameters to validate: user_agent, ip_address, expiration.
|
||||
*/
|
||||
$config['validate'] = array('user_agent');
|
||||
|
||||
/**
|
||||
* Enable or disable session encryption.
|
||||
* Note: this has no effect on the native session driver.
|
||||
*/
|
||||
$config['encryption'] = FALSE;
|
||||
|
||||
/**
|
||||
* Session lifetime. Number of seconds that each session will last.
|
||||
* A value of 0 will keep the session active until the browser is closed (with a limit of 24h).
|
||||
*/
|
||||
$config['expiration'] = 7200;
|
||||
|
||||
/**
|
||||
* Number of page loads before the session id is regenerated.
|
||||
* A value of 0 will disable automatic session id regeneration.
|
||||
* NOTE: Enabling automatic session regeneration can cause a race condition see the
|
||||
* docs for details: http://docs.kohanaphp.com/libraries/session#regenerate
|
||||
*/
|
||||
$config['regenerate'] = 0;
|
||||
|
||||
/**
|
||||
* Percentage probability that the gc (garbage collection) routine is started.
|
||||
*/
|
||||
$config['gc_probability'] = 2;
|
93
web_client/system/config/sql_types.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Database
|
||||
*
|
||||
* SQL data types. If there are missing values, please report them:
|
||||
*
|
||||
* @link http://dev.kohanaphp.com/projects/kohana2
|
||||
*/
|
||||
$config = array
|
||||
(
|
||||
// SQL-92
|
||||
'bit' => array('type' => 'string', 'exact' => TRUE),
|
||||
'bit varying' => array('type' => 'string'),
|
||||
'character' => array('type' => 'string', 'exact' => TRUE),
|
||||
'character varying' => array('type' => 'string'),
|
||||
'date' => array('type' => 'string'),
|
||||
'decimal' => array('type' => 'float', 'exact' => TRUE),
|
||||
'double precision' => array('type' => 'float'),
|
||||
'float' => array('type' => 'float'),
|
||||
'integer' => array('type' => 'int', 'min' => -2147483648, 'max' => 2147483647),
|
||||
'interval' => array('type' => 'string'),
|
||||
'national character' => array('type' => 'string', 'exact' => TRUE),
|
||||
'national character varying' => array('type' => 'string'),
|
||||
'numeric' => array('type' => 'float', 'exact' => TRUE),
|
||||
'real' => array('type' => 'float'),
|
||||
'smallint' => array('type' => 'int', 'min' => -32768, 'max' => 32767),
|
||||
'time' => array('type' => 'string'),
|
||||
'time with time zone' => array('type' => 'string'),
|
||||
'timestamp' => array('type' => 'string'),
|
||||
'timestamp with time zone' => array('type' => 'string'),
|
||||
|
||||
// SQL:1999
|
||||
//'array','ref','row'
|
||||
'binary large object' => array('type' => 'string', 'binary' => TRUE),
|
||||
'boolean' => array('type' => 'boolean'),
|
||||
'character large object' => array('type' => 'string'),
|
||||
'national character large object' => array('type' => 'string'),
|
||||
|
||||
// SQL:2003
|
||||
'bigint' => array('type' => 'int', 'min' => -9223372036854775808, 'max' => 9223372036854775807),
|
||||
|
||||
// SQL:2008
|
||||
'binary' => array('type' => 'string', 'binary' => TRUE, 'exact' => TRUE),
|
||||
'binary varying' => array('type' => 'string', 'binary' => TRUE),
|
||||
|
||||
// MySQL
|
||||
'bigint unsigned' => array('type' => 'int', 'min' => 0, 'max' => 18446744073709551615),
|
||||
'decimal unsigned' => array('type' => 'float', 'exact' => TRUE, 'min' => 0.0),
|
||||
'double unsigned' => array('type' => 'float', 'min' => 0.0),
|
||||
'float unsigned' => array('type' => 'float', 'min' => 0.0),
|
||||
'integer unsigned' => array('type' => 'int', 'min' => 0, 'max' => 4294967295),
|
||||
'mediumint' => array('type' => 'int', 'min' => -8388608, 'max' => 8388607),
|
||||
'mediumint unsigned' => array('type' => 'int', 'min' => 0, 'max' => 16777215),
|
||||
'real unsigned' => array('type' => 'float', 'min' => 0.0),
|
||||
'smallint unsigned' => array('type' => 'int', 'min' => 0, 'max' => 65535),
|
||||
'text' => array('type' => 'string'),
|
||||
'tinyint' => array('type' => 'int', 'min' => -128, 'max' => 127),
|
||||
'tinyint unsigned' => array('type' => 'int', 'min' => 0, 'max' => 255),
|
||||
'year' => array('type' => 'string'),
|
||||
);
|
||||
|
||||
// SQL-92
|
||||
$config['char'] = $config['character'];
|
||||
$config['char varying'] = $config['character varying'];
|
||||
$config['dec'] = $config['decimal'];
|
||||
$config['int'] = $config['integer'];
|
||||
$config['nchar'] = $config['national char'] = $config['national character'];
|
||||
$config['nchar varying'] = $config['national char varying'] = $config['national character varying'];
|
||||
$config['varchar'] = $config['character varying'];
|
||||
|
||||
// SQL:1999
|
||||
$config['blob'] = $config['binary large object'];
|
||||
$config['clob'] = $config['char large object'] = $config['character large object'];
|
||||
$config['nclob'] = $config['nchar large object'] = $config['national character large object'];
|
||||
$config['time without time zone'] = $config['time'];
|
||||
$config['timestamp without time zone'] = $config['timestamp'];
|
||||
|
||||
// SQL:2008
|
||||
$config['varbinary'] = $config['binary varying'];
|
||||
|
||||
// MySQL
|
||||
$config['bool'] = $config['boolean'];
|
||||
$config['datetime'] = $config['timestamp'];
|
||||
$config['double'] = $config['double precision'];
|
||||
$config['double precision unsigned'] = $config['double unsigned'];
|
||||
$config['enum'] = $config['set'] = $config['character varying'];
|
||||
$config['fixed'] = $config['decimal'];
|
||||
$config['fixed unsigned'] = $config['decimal unsigned'];
|
||||
$config['int unsigned'] = $config['integer unsigned'];
|
||||
$config['longblob'] = $config['mediumblob'] = $config['tinyblob'] = $config['binary large object'];
|
||||
$config['longtext'] = $config['mediumtext'] = $config['tinytext'] = $config['text'];
|
||||
$config['numeric unsigned'] = $config['decimal unsigned'];
|
||||
$config['nvarchar'] = $config['national varchar'] = $config['national character varying'];
|
17
web_client/system/config/upload.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* This path is relative to your index file. Absolute paths are also supported.
|
||||
*/
|
||||
$config['directory'] = DOCROOT.'upload';
|
||||
|
||||
/**
|
||||
* Enable or disable directory creation.
|
||||
*/
|
||||
$config['create_directories'] = FALSE;
|
||||
|
||||
/**
|
||||
* Remove spaces from uploaded filenames.
|
||||
*/
|
||||
$config['remove_spaces'] = TRUE;
|
112
web_client/system/config/user_agents.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* This file contains four arrays of user agent data. It is used by the
|
||||
* User Agent library to help identify browser, platform, robot, and
|
||||
* mobile device data. The array keys are used to identify the device
|
||||
* and the array values are used to set the actual name of the item.
|
||||
*/
|
||||
$config['platform'] = array
|
||||
(
|
||||
'windows nt 6.0' => 'Windows Vista',
|
||||
'windows nt 5.2' => 'Windows 2003',
|
||||
'windows nt 5.0' => 'Windows 2000',
|
||||
'windows nt 5.1' => 'Windows XP',
|
||||
'windows nt 4.0' => 'Windows NT',
|
||||
'winnt4.0' => 'Windows NT',
|
||||
'winnt 4.0' => 'Windows NT',
|
||||
'winnt' => 'Windows NT',
|
||||
'windows 98' => 'Windows 98',
|
||||
'win98' => 'Windows 98',
|
||||
'windows 95' => 'Windows 95',
|
||||
'win95' => 'Windows 95',
|
||||
'windows' => 'Unknown Windows OS',
|
||||
'os x' => 'Mac OS X',
|
||||
'intel mac' => 'Intel Mac',
|
||||
'ppc mac' => 'PowerPC Mac',
|
||||
'powerpc' => 'PowerPC',
|
||||
'ppc' => 'PowerPC',
|
||||
'cygwin' => 'Cygwin',
|
||||
'linux' => 'Linux',
|
||||
'debian' => 'Debian',
|
||||
'openvms' => 'OpenVMS',
|
||||
'sunos' => 'Sun Solaris',
|
||||
'amiga' => 'Amiga',
|
||||
'beos' => 'BeOS',
|
||||
'apachebench' => 'ApacheBench',
|
||||
'freebsd' => 'FreeBSD',
|
||||
'netbsd' => 'NetBSD',
|
||||
'bsdi' => 'BSDi',
|
||||
'openbsd' => 'OpenBSD',
|
||||
'os/2' => 'OS/2',
|
||||
'warp' => 'OS/2',
|
||||
'aix' => 'AIX',
|
||||
'irix' => 'Irix',
|
||||
'osf' => 'DEC OSF',
|
||||
'hp-ux' => 'HP-UX',
|
||||
'hurd' => 'GNU/Hurd',
|
||||
'unix' => 'Unknown Unix OS',
|
||||
);
|
||||
|
||||
// The order of this array should NOT be changed. Many browsers return
|
||||
// multiple browser types so we want to identify the sub-type first.
|
||||
$config['browser'] = array
|
||||
(
|
||||
'Opera' => 'Opera',
|
||||
'MSIE' => 'Internet Explorer',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Shiira' => 'Shiira',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chimera' => 'Chimera',
|
||||
'Phoenix' => 'Phoenix',
|
||||
'Firebird' => 'Firebird',
|
||||
'Camino' => 'Camino',
|
||||
'Netscape' => 'Netscape',
|
||||
'OmniWeb' => 'OmniWeb',
|
||||
'Chrome' => 'Chrome',
|
||||
'Safari' => 'Safari',
|
||||
'Konqueror' => 'Konqueror',
|
||||
'Epiphany' => 'Epiphany',
|
||||
'Galeon' => 'Galeon',
|
||||
'Mozilla' => 'Mozilla',
|
||||
'icab' => 'iCab',
|
||||
'lynx' => 'Lynx',
|
||||
'links' => 'Links',
|
||||
'hotjava' => 'HotJava',
|
||||
'amaya' => 'Amaya',
|
||||
'IBrowse' => 'IBrowse',
|
||||
);
|
||||
|
||||
$config['mobile'] = array
|
||||
(
|
||||
'mobileexplorer' => 'Mobile Explorer',
|
||||
'openwave' => 'Open Wave',
|
||||
'opera mini' => 'Opera Mini',
|
||||
'operamini' => 'Opera Mini',
|
||||
'elaine' => 'Palm',
|
||||
'palmsource' => 'Palm',
|
||||
'digital paths' => 'Palm',
|
||||
'avantgo' => 'Avantgo',
|
||||
'xiino' => 'Xiino',
|
||||
'palmscape' => 'Palmscape',
|
||||
'nokia' => 'Nokia',
|
||||
'ericsson' => 'Ericsson',
|
||||
'blackBerry' => 'BlackBerry',
|
||||
'motorola' => 'Motorola',
|
||||
'iphone' => 'iPhone',
|
||||
'android' => 'Android',
|
||||
);
|
||||
|
||||
// There are hundreds of bots but these are the most common.
|
||||
$config['robot'] = array
|
||||
(
|
||||
'googlebot' => 'Googlebot',
|
||||
'msnbot' => 'MSNBot',
|
||||
'slurp' => 'Inktomi Slurp',
|
||||
'yahoo' => 'Yahoo',
|
||||
'askjeeves' => 'AskJeeves',
|
||||
'fastcrawler' => 'FastCrawler',
|
||||
'infoseek' => 'InfoSeek Robot 1.0',
|
||||
'lycos' => 'Lycos',
|
||||
);
|
18
web_client/system/config/view.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* @package Core
|
||||
*
|
||||
* Allowed non-php view types. Most file extensions are supported.
|
||||
* Do not forget to add a valid MIME type in mimes.php
|
||||
*/
|
||||
$config['allowed_filetypes'] = array
|
||||
(
|
||||
'gif',
|
||||
'jpg', 'jpeg',
|
||||
'png',
|
||||
'tif', 'tiff',
|
||||
'swf',
|
||||
'htm', 'html',
|
||||
'css',
|
||||
'js'
|
||||
);
|
23
web_client/system/controllers/captcha.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Outputs the dynamic Captcha resource.
|
||||
* Usage: Call the Captcha controller from a view, e.g.
|
||||
* <img src="<?php echo url::site('captcha') ?>" />
|
||||
*
|
||||
* $Id: captcha.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Captcha
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Captcha_Controller extends Controller {
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// Output the Captcha challenge resource (no html)
|
||||
// Pull the config group name from the URL
|
||||
Captcha::factory($this->uri->segment(2))->render(FALSE);
|
||||
}
|
||||
|
||||
} // End Captcha_Controller
|
54
web_client/system/controllers/template.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Allows a template to be automatically loaded and displayed. Display can be
|
||||
* dynamically turned off in the controller methods, and the template file
|
||||
* can be overloaded.
|
||||
*
|
||||
* To use it, declare your controller to extend this class:
|
||||
* `class Your_Controller extends Template_Controller`
|
||||
*
|
||||
* $Id: template.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Template_Controller extends Controller {
|
||||
|
||||
// Template view name
|
||||
public $template = 'template';
|
||||
|
||||
// Default to do auto-rendering
|
||||
public $auto_render = TRUE;
|
||||
|
||||
/**
|
||||
* Template loading and setup routine.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// Load the template
|
||||
$this->template = new View($this->template);
|
||||
|
||||
if ($this->auto_render == TRUE)
|
||||
{
|
||||
// Render the template immediately after the controller method
|
||||
Event::add('system.post_controller', array($this, '_render'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the loaded template.
|
||||
*/
|
||||
public function _render()
|
||||
{
|
||||
if ($this->auto_render == TRUE)
|
||||
{
|
||||
// Render the template when the class is destroyed
|
||||
$this->template->render(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
} // End Template_Controller
|
128
web_client/system/core/Benchmark.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Simple benchmarking.
|
||||
*
|
||||
* $Id: Benchmark.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
final class Benchmark {
|
||||
|
||||
// Benchmark timestamps
|
||||
private static $marks;
|
||||
|
||||
/**
|
||||
* Set a benchmark start point.
|
||||
*
|
||||
* @param string benchmark name
|
||||
* @return void
|
||||
*/
|
||||
public static function start($name)
|
||||
{
|
||||
if (isset(self::$marks[$name]) AND self::$marks[$name][0]['stop'] === FALSE)
|
||||
throw new Kohana_Exception('A benchmark named :name is already running.', array(':name' => $name));
|
||||
|
||||
if ( ! isset(self::$marks[$name]))
|
||||
{
|
||||
self::$marks[$name] = array();
|
||||
}
|
||||
|
||||
$mark = array
|
||||
(
|
||||
'start' => microtime(TRUE),
|
||||
'stop' => FALSE,
|
||||
'memory_start' => self::memory_usage(),
|
||||
'memory_stop' => FALSE
|
||||
);
|
||||
|
||||
array_unshift(self::$marks[$name], $mark);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a benchmark stop point.
|
||||
*
|
||||
* @param string benchmark name
|
||||
* @return void
|
||||
*/
|
||||
public static function stop($name)
|
||||
{
|
||||
if (isset(self::$marks[$name]) AND self::$marks[$name][0]['stop'] === FALSE)
|
||||
{
|
||||
self::$marks[$name][0]['stop'] = microtime(TRUE);
|
||||
self::$marks[$name][0]['memory_stop'] = self::memory_usage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elapsed time between a start and stop.
|
||||
*
|
||||
* @param string benchmark name, TRUE for all
|
||||
* @param integer number of decimal places to count to
|
||||
* @return array
|
||||
*/
|
||||
public static function get($name, $decimals = 4)
|
||||
{
|
||||
if ($name === TRUE)
|
||||
{
|
||||
$times = array();
|
||||
$names = array_keys(self::$marks);
|
||||
|
||||
foreach ($names as $name)
|
||||
{
|
||||
// Get each mark recursively
|
||||
$times[$name] = self::get($name, $decimals);
|
||||
}
|
||||
|
||||
// Return the array
|
||||
return $times;
|
||||
}
|
||||
|
||||
if ( ! isset(self::$marks[$name]))
|
||||
return FALSE;
|
||||
|
||||
if (self::$marks[$name][0]['stop'] === FALSE)
|
||||
{
|
||||
// Stop the benchmark to prevent mis-matched results
|
||||
self::stop($name);
|
||||
}
|
||||
|
||||
// Return a string version of the time between the start and stop points
|
||||
// Properly reading a float requires using number_format or sprintf
|
||||
$time = $memory = 0;
|
||||
for ($i = 0; $i < count(self::$marks[$name]); $i++)
|
||||
{
|
||||
$time += self::$marks[$name][$i]['stop'] - self::$marks[$name][$i]['start'];
|
||||
$memory += self::$marks[$name][$i]['memory_stop'] - self::$marks[$name][$i]['memory_start'];
|
||||
}
|
||||
|
||||
return array
|
||||
(
|
||||
'time' => number_format($time, $decimals),
|
||||
'memory' => $memory,
|
||||
'count' => count(self::$marks[$name])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current memory usage. This is only possible if the
|
||||
* memory_get_usage function is supported in PHP.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private static function memory_usage()
|
||||
{
|
||||
static $func;
|
||||
|
||||
if ($func === NULL)
|
||||
{
|
||||
// Test if memory usage can be seen
|
||||
$func = function_exists('memory_get_usage');
|
||||
}
|
||||
|
||||
return $func ? memory_get_usage() : 0;
|
||||
}
|
||||
|
||||
} // End Benchmark
|
233
web_client/system/core/Event.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Process queuing/execution class. Allows an unlimited number of callbacks
|
||||
* to be added to 'events'. Events can be run multiple times, and can also
|
||||
* process event-specific data. By default, Kohana has several system events.
|
||||
*
|
||||
* $Id: Event.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @link http://docs.kohanaphp.com/general/events
|
||||
*/
|
||||
abstract class Event_Core {
|
||||
|
||||
// Event callbacks
|
||||
protected static $events = array();
|
||||
|
||||
// Cache of events that have been run
|
||||
protected static $has_run = array();
|
||||
|
||||
// Data that can be processed during events
|
||||
public static $data;
|
||||
|
||||
/**
|
||||
* Add a callback to an event queue.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array http://php.net/callback
|
||||
* @param boolean prevent duplicates
|
||||
* @return boolean
|
||||
*/
|
||||
public static function add($name, $callback, $unique = FALSE)
|
||||
{
|
||||
if ( ! isset(Event::$events[$name]))
|
||||
{
|
||||
// Create an empty event if it is not yet defined
|
||||
Event::$events[$name] = array();
|
||||
}
|
||||
elseif ($unique AND in_array($callback, Event::$events[$name], TRUE))
|
||||
{
|
||||
// The event already exists
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add the event
|
||||
Event::$events[$name][] = $callback;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback to an event queue, before a given event.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array existing event callback
|
||||
* @param array event callback
|
||||
* @return boolean
|
||||
*/
|
||||
public static function add_before($name, $existing, $callback)
|
||||
{
|
||||
if (empty(Event::$events[$name]) OR ($key = array_search($existing, Event::$events[$name])) === FALSE)
|
||||
{
|
||||
// Just add the event if there are no events
|
||||
return Event::add($name, $callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert the event immediately before the existing event
|
||||
return Event::insert_event($name, $key, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback to an event queue, after a given event.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array existing event callback
|
||||
* @param array event callback
|
||||
* @return boolean
|
||||
*/
|
||||
public static function add_after($name, $existing, $callback)
|
||||
{
|
||||
if (empty(Event::$events[$name]) OR ($key = array_search($existing, Event::$events[$name])) === FALSE)
|
||||
{
|
||||
// Just add the event if there are no events
|
||||
return Event::add($name, $callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert the event immediately after the existing event
|
||||
return Event::insert_event($name, $key + 1, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new event at a specfic key location.
|
||||
*
|
||||
* @param string event name
|
||||
* @param integer key to insert new event at
|
||||
* @param array event callback
|
||||
* @return void
|
||||
*/
|
||||
private static function insert_event($name, $key, $callback)
|
||||
{
|
||||
if (in_array($callback, Event::$events[$name], TRUE))
|
||||
return FALSE;
|
||||
|
||||
// Add the new event at the given key location
|
||||
Event::$events[$name] = array_merge
|
||||
(
|
||||
// Events before the key
|
||||
array_slice(Event::$events[$name], 0, $key),
|
||||
// New event callback
|
||||
array($callback),
|
||||
// Events after the key
|
||||
array_slice(Event::$events[$name], $key)
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an event with another event.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array event to replace
|
||||
* @param array new callback
|
||||
* @return boolean
|
||||
*/
|
||||
public static function replace($name, $existing, $callback)
|
||||
{
|
||||
if (empty(Event::$events[$name]) OR ($key = array_search($existing, Event::$events[$name], TRUE)) === FALSE)
|
||||
return FALSE;
|
||||
|
||||
if ( ! in_array($callback, Event::$events[$name], TRUE))
|
||||
{
|
||||
// Replace the exisiting event with the new event
|
||||
Event::$events[$name][$key] = $callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the existing event from the queue
|
||||
unset(Event::$events[$name][$key]);
|
||||
|
||||
// Reset the array so the keys are ordered properly
|
||||
Event::$events[$name] = array_values(Event::$events[$name]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all callbacks for an event.
|
||||
*
|
||||
* @param string event name
|
||||
* @return array
|
||||
*/
|
||||
public static function get($name)
|
||||
{
|
||||
return empty(Event::$events[$name]) ? array() : Event::$events[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear some or all callbacks from an event.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array specific callback to remove, FALSE for all callbacks
|
||||
* @return void
|
||||
*/
|
||||
public static function clear($name, $callback = FALSE)
|
||||
{
|
||||
if ($callback === FALSE)
|
||||
{
|
||||
Event::$events[$name] = array();
|
||||
}
|
||||
elseif (isset(Event::$events[$name]))
|
||||
{
|
||||
// Loop through each of the event callbacks and compare it to the
|
||||
// callback requested for removal. The callback is removed if it
|
||||
// matches.
|
||||
foreach (Event::$events[$name] as $i => $event_callback)
|
||||
{
|
||||
if ($callback === $event_callback)
|
||||
{
|
||||
unset(Event::$events[$name][$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all of the callbacks attached to an event.
|
||||
*
|
||||
* @param string event name
|
||||
* @param array data can be processed as Event::$data by the callbacks
|
||||
* @return void
|
||||
*/
|
||||
public static function run($name, & $data = NULL)
|
||||
{
|
||||
if ( ! empty(Event::$events[$name]))
|
||||
{
|
||||
// So callbacks can access Event::$data
|
||||
Event::$data =& $data;
|
||||
$callbacks = Event::get($name);
|
||||
|
||||
foreach ($callbacks as $callback)
|
||||
{
|
||||
call_user_func_array($callback, array(&$data));
|
||||
}
|
||||
|
||||
// Do this to prevent data from getting 'stuck'
|
||||
$clear_data = '';
|
||||
Event::$data =& $clear_data;
|
||||
}
|
||||
|
||||
// The event has been run!
|
||||
Event::$has_run[$name] = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given event has been run.
|
||||
*
|
||||
* @param string event name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function has_run($name)
|
||||
{
|
||||
return isset(Event::$has_run[$name]);
|
||||
}
|
||||
|
||||
} // End Event
|
1096
web_client/system/core/Kohana.php
Normal file
331
web_client/system/core/Kohana_Config.php
Normal file
@ -0,0 +1,331 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Provides a driver-based interface for setting and getting
|
||||
* configuration options for the Kohana environment
|
||||
*
|
||||
* $Id: Kohana_Config.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package KohanaConfig
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Config_Core implements ArrayAccess {
|
||||
|
||||
/**
|
||||
* The default Kohana_Config driver
|
||||
* to use for system setup
|
||||
*
|
||||
* @var string
|
||||
* @static
|
||||
*/
|
||||
public static $default_driver = 'array';
|
||||
|
||||
/**
|
||||
* Kohana_Config instance
|
||||
*
|
||||
* @var array
|
||||
* @static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Returns a new instance of the Kohana_Config library
|
||||
* based on the singleton pattern
|
||||
*
|
||||
* @param string driver
|
||||
* @return Kohana_Config
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function & instance()
|
||||
{
|
||||
// If the driver has not been initialised, intialise it
|
||||
if ( empty(Kohana_Config::$instance))
|
||||
{
|
||||
//call a 1 time non singleton of Kohana_Config to get a list of drivers
|
||||
$config = new Kohana_Config(array(
|
||||
'config_drivers'=>array(
|
||||
), 'internal_cache'=>FALSE
|
||||
));
|
||||
$core_config = $config->get('core');
|
||||
Kohana_Config::$instance = new Kohana_Config($core_config);
|
||||
}
|
||||
|
||||
// Return the Kohana_Config driver requested
|
||||
return Kohana_Config::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* The drivers for this object
|
||||
*
|
||||
* @var Kohana_Config_Driver
|
||||
*/
|
||||
protected $drivers;
|
||||
|
||||
/**
|
||||
* Kohana_Config constructor to load the supplied driver.
|
||||
* Enforces the singleton pattern.
|
||||
*
|
||||
* @param string driver
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct(array $core_config)
|
||||
{
|
||||
$drivers = $core_config['config_drivers'];
|
||||
|
||||
//remove array if it's found in config
|
||||
if (in_array('array', $drivers))
|
||||
unset($drivers[array_search('array', $drivers)]);
|
||||
|
||||
//add array at the very end
|
||||
$this->drivers = $drivers = array_merge($drivers, array(
|
||||
'array'
|
||||
));
|
||||
|
||||
foreach ($this->drivers as & $driver)
|
||||
{
|
||||
// Create the driver name
|
||||
$driver = 'Config_'.ucfirst($driver).'_Driver';
|
||||
|
||||
// Ensure the driver loads correctly
|
||||
if (!Kohana::auto_load($driver))
|
||||
throw new Kohana_Exception('The :driver: driver for the :library: library could not be found.', array(
|
||||
':driver:' => $driver, ':library:' => get_class($this)
|
||||
));
|
||||
|
||||
// Load the new driver
|
||||
$driver = new $driver($core_config);
|
||||
|
||||
// Ensure the new driver is valid
|
||||
if (!$driver instanceof Config_Driver)
|
||||
throw new Kohana_Exception('The :driver: driver for the :library: library must implement the :interface: interface', array(
|
||||
':driver:' => $driver, ':library:' => get_class($this), ':interface:' => 'Config_Driver'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from the configuration driver
|
||||
*
|
||||
* @param string key
|
||||
* @param bool slash
|
||||
* @param bool required
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
public function get($key, $slash = FALSE, $required = FALSE)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $driver->get($key, $slash, $required);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value to the configuration drivers
|
||||
*
|
||||
* @param string key
|
||||
* @param mixed value
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
$driver->set($key, $value);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a group from configuration
|
||||
*
|
||||
* @param string group
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function clear($group)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
$driver->clear($group);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a configuration group
|
||||
*
|
||||
* @param string group
|
||||
* @param bool required
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function load($group, $required = FALSE)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $driver->load($group, $required);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true or false if any config has been loaded(either manually or from cache)
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function loaded()
|
||||
{
|
||||
return $this->drivers[(count($this->drivers) - 1)]->loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following allows access using
|
||||
* array syntax.
|
||||
*
|
||||
* @example $config['core.site_domain']
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows access to configuration settings
|
||||
* using the ArrayAccess interface
|
||||
*
|
||||
* @param string key
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $driver->get($key);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows access to configuration settings
|
||||
* using the ArrayAccess interface
|
||||
*
|
||||
* @param string key
|
||||
* @param mixed value
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
$driver->set($key, $value);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows access to configuration settings
|
||||
* using the ArrayAccess interface
|
||||
*
|
||||
* @param string key
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $driver->setting_exists($key);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows access to configuration settings
|
||||
* using the ArrayAccess interface
|
||||
*
|
||||
* @param string key
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
foreach ($this->drivers as $driver)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $driver->set($key, NULL);
|
||||
}
|
||||
catch (Kohana_Config_Exception $e)
|
||||
{
|
||||
//if it's the last driver in the list and it threw an exception, re throw it
|
||||
if ($driver === $this->drivers[(count($this->drivers) - 1)])
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
} // End KohanaConfig
|
||||
|
||||
class Kohana_Config_Exception extends Kohana_Exception {}
|
619
web_client/system/core/Kohana_Exception.php
Normal file
@ -0,0 +1,619 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Kohana Exceptions
|
||||
*
|
||||
* $Id: Kohana_Exception.php 4692 2009-12-04 15:59:44Z cbandy $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
|
||||
class Kohana_Exception_Core extends Exception {
|
||||
|
||||
public static $enabled = FALSE;
|
||||
|
||||
// Template file
|
||||
public static $template = 'kohana/error';
|
||||
|
||||
// Show stack traces in errors
|
||||
public static $trace_output = TRUE;
|
||||
|
||||
// Show source code in errors
|
||||
public static $source_output = TRUE;
|
||||
|
||||
// To hold unique identifier to distinguish error output
|
||||
protected $instance_identifier;
|
||||
|
||||
// Error code
|
||||
protected $code = E_KOHANA;
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* @param string error message
|
||||
* @param array translation variables
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message, array $variables = NULL, $code = 0)
|
||||
{
|
||||
$this->instance_identifier = uniqid();
|
||||
|
||||
// Translate the error message
|
||||
$message = __($message, $variables);
|
||||
|
||||
// Sets $this->message the proper way
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Kohana exception handling.
|
||||
*
|
||||
* @uses Kohana_Exception::$template
|
||||
* @return void
|
||||
*/
|
||||
public static function enable()
|
||||
{
|
||||
if ( ! Kohana_Exception::$enabled)
|
||||
{
|
||||
set_exception_handler(array('Kohana_Exception', 'handle'));
|
||||
|
||||
Kohana_Exception::$enabled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable Kohana exception handling.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function disable()
|
||||
{
|
||||
if (Kohana_Exception::$enabled)
|
||||
{
|
||||
restore_exception_handler();
|
||||
|
||||
Kohana_Exception::$enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single line of text representing the exception:
|
||||
*
|
||||
* Error [ Code ]: Message ~ File [ Line ]
|
||||
*
|
||||
* @param object Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function text($e)
|
||||
{
|
||||
return sprintf('%s [ %s ]: %s ~ %s [ %d ]',
|
||||
get_class($e), $e->getCode(), strip_tags($e->getMessage()), Kohana_Exception::debug_path($e->getFile()), $e->getLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* exception handler, displays the error message, source of the
|
||||
* exception, and the stack trace of the error.
|
||||
*
|
||||
* @uses Kohana::message()
|
||||
* @uses Kohana_Exception::text()
|
||||
* @param object exception object
|
||||
* @return void
|
||||
*/
|
||||
public static function handle(Exception $e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the exception information
|
||||
$type = get_class($e);
|
||||
$code = $e->getCode();
|
||||
$message = $e->getMessage();
|
||||
|
||||
// Create a text version of the exception
|
||||
$error = Kohana_Exception::text($e);
|
||||
|
||||
// Add this exception to the log
|
||||
Kohana_Log::add('error', $error);
|
||||
|
||||
// Manually save logs after exceptions
|
||||
Kohana_Log::save();
|
||||
|
||||
if (Kohana::config('core.display_errors') === FALSE)
|
||||
{
|
||||
// Do not show the details
|
||||
$file = $line = NULL;
|
||||
$trace = array();
|
||||
|
||||
$template = '_disabled';
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = $e->getFile();
|
||||
$line = $e->getLine();
|
||||
$trace = $e->getTrace();
|
||||
|
||||
$template = '';
|
||||
}
|
||||
|
||||
if ($e instanceof Kohana_Exception)
|
||||
{
|
||||
$template = $e->getTemplate().$template;
|
||||
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
$e->sendHeaders();
|
||||
}
|
||||
|
||||
// Use the human-readable error name
|
||||
$code = Kohana::message('core.errors.'.$code);
|
||||
}
|
||||
else
|
||||
{
|
||||
$template = Kohana_Exception::$template.$template;
|
||||
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
|
||||
if ($e instanceof ErrorException)
|
||||
{
|
||||
// Use the human-readable error name
|
||||
$code = Kohana::message('core.errors.'.$e->getSeverity());
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3', '<'))
|
||||
{
|
||||
// Workaround for a bug in ErrorException::getTrace() that exists in
|
||||
// all PHP 5.2 versions. @see http://bugs.php.net/45895
|
||||
for ($i = count($trace) - 1; $i > 0; --$i)
|
||||
{
|
||||
if (isset($trace[$i - 1]['args']))
|
||||
{
|
||||
// Re-position the arguments
|
||||
$trace[$i]['args'] = $trace[$i - 1]['args'];
|
||||
|
||||
unset($trace[$i - 1]['args']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean the output buffer if one exists
|
||||
ob_get_level() and ob_clean();
|
||||
|
||||
if ($template = Kohana::find_file('views', $template))
|
||||
{
|
||||
include $template;
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Clean the output buffer if one exists
|
||||
ob_get_level() and ob_clean();
|
||||
|
||||
// Display the exception text
|
||||
echo Kohana_Exception::text($e), "\n";
|
||||
}
|
||||
|
||||
if (Kohana::$server_api === 'cli')
|
||||
{
|
||||
// Exit with an error status
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the template for this exception.
|
||||
*
|
||||
* @uses Kohana_Exception::$template
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplate()
|
||||
{
|
||||
return Kohana_Exception::$template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an Internal Server Error header.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendHeaders()
|
||||
{
|
||||
// Send the 500 header
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string of information about a single variable.
|
||||
*
|
||||
* Borrows heavily on concepts from the Debug class of {@link http://nettephp.com/ Nette}.
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @return string
|
||||
*/
|
||||
public static function dump($value, $length = 128)
|
||||
{
|
||||
return Kohana_Exception::_dump($value, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for Kohana_Exception::dump(), handles recursion in arrays and objects.
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @param integer recursion level (internal)
|
||||
* @return string
|
||||
*/
|
||||
private static function _dump( & $var, $length = 128, $level = 0)
|
||||
{
|
||||
if ($var === NULL)
|
||||
{
|
||||
return '<small>NULL</small>';
|
||||
}
|
||||
elseif (is_bool($var))
|
||||
{
|
||||
return '<small>bool</small> '.($var ? 'TRUE' : 'FALSE');
|
||||
}
|
||||
elseif (is_float($var))
|
||||
{
|
||||
return '<small>float</small> '.$var;
|
||||
}
|
||||
elseif (is_resource($var))
|
||||
{
|
||||
if (($type = get_resource_type($var)) === 'stream' AND $meta = stream_get_meta_data($var))
|
||||
{
|
||||
$meta = stream_get_meta_data($var);
|
||||
|
||||
if (isset($meta['uri']))
|
||||
{
|
||||
$file = $meta['uri'];
|
||||
|
||||
if (function_exists('stream_is_local'))
|
||||
{
|
||||
// Only exists on PHP >= 5.2.4
|
||||
if (stream_is_local($file))
|
||||
{
|
||||
$file = Kohana_Exception::debug_path($file);
|
||||
}
|
||||
}
|
||||
|
||||
return '<small>resource</small><span>('.$type.')</span> '.htmlspecialchars($file, ENT_NOQUOTES, Kohana::CHARSET);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>resource</small><span>('.$type.')</span>';
|
||||
}
|
||||
}
|
||||
elseif (is_string($var))
|
||||
{
|
||||
if (strlen($var) > $length)
|
||||
{
|
||||
// Encode the truncated string
|
||||
$str = htmlspecialchars(substr($var, 0, $length), ENT_NOQUOTES, Kohana::CHARSET).' …';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Encode the string
|
||||
$str = htmlspecialchars($var, ENT_NOQUOTES, Kohana::CHARSET);
|
||||
}
|
||||
|
||||
return '<small>string</small><span>('.strlen($var).')</span> "'.$str.'"';
|
||||
}
|
||||
elseif (is_array($var))
|
||||
{
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
static $marker;
|
||||
|
||||
if ($marker === NULL)
|
||||
{
|
||||
// Make a unique marker
|
||||
$marker = uniqid("\x00");
|
||||
}
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($var[$marker]))
|
||||
{
|
||||
$output[] = "(\n$space$s*RECURSION*\n$space)";
|
||||
}
|
||||
elseif ($level < 5)
|
||||
{
|
||||
$output[] = "<span>(";
|
||||
|
||||
$var[$marker] = TRUE;
|
||||
foreach ($var as $key => & $val)
|
||||
{
|
||||
if ($key === $marker) continue;
|
||||
if ( ! is_int($key))
|
||||
{
|
||||
$key = '"'.$key.'"';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$key => ".Kohana_Exception::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($var[$marker]);
|
||||
|
||||
$output[] = "$space)</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "(\n$space$s...\n$space)";
|
||||
}
|
||||
|
||||
return '<small>array</small><span>('.count($var).')</span> '.implode("\n", $output);
|
||||
}
|
||||
elseif (is_object($var))
|
||||
{
|
||||
// Copy the object as an array
|
||||
$array = (array) $var;
|
||||
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
$hash = spl_object_hash($var);
|
||||
|
||||
// Objects that are being dumped
|
||||
static $objects = array();
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($objects[$hash]))
|
||||
{
|
||||
$output[] = "{\n$space$s*RECURSION*\n$space}";
|
||||
}
|
||||
elseif ($level < 5)
|
||||
{
|
||||
$output[] = "<code>{";
|
||||
|
||||
$objects[$hash] = TRUE;
|
||||
foreach ($array as $key => & $val)
|
||||
{
|
||||
if ($key[0] === "\x00")
|
||||
{
|
||||
// Determine if the access is private or protected
|
||||
$access = '<small>'.($key[1] === '*' ? 'protected' : 'private').'</small>';
|
||||
|
||||
// Remove the access level from the variable name
|
||||
$key = substr($key, strrpos($key, "\x00") + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$access = '<small>public</small>';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$access $key => ".Kohana_Exception::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($objects[$hash]);
|
||||
|
||||
$output[] = "$space}</code>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "{\n$space$s...\n$space}";
|
||||
}
|
||||
|
||||
return '<small>object</small> <span>'.get_class($var).'('.count($array).')</span> '.implode("\n", $output);
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>'.gettype($var).'</small> '.htmlspecialchars(print_r($var, TRUE), ENT_NOQUOTES, Kohana::CHARSET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes APPPATH, SYSPATH, MODPATH, and DOCROOT from filenames, replacing
|
||||
* them with the plain text equivalents.
|
||||
*
|
||||
* @param string path to sanitize
|
||||
* @return string
|
||||
*/
|
||||
public static function debug_path($file)
|
||||
{
|
||||
if (strpos($file, APPPATH) === 0)
|
||||
{
|
||||
$file = 'APPPATH/'.substr($file, strlen(APPPATH));
|
||||
}
|
||||
elseif (strpos($file, SYSPATH) === 0)
|
||||
{
|
||||
$file = 'SYSPATH/'.substr($file, strlen(SYSPATH));
|
||||
}
|
||||
elseif (strpos($file, MODPATH) === 0)
|
||||
{
|
||||
$file = 'MODPATH/'.substr($file, strlen(MODPATH));
|
||||
}
|
||||
elseif (strpos($file, DOCROOT) === 0)
|
||||
{
|
||||
$file = 'DOCROOT/'.substr($file, strlen(DOCROOT));
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of lines from a file.
|
||||
*
|
||||
* // Returns the current line of the current file
|
||||
* echo Kohana_Exception::debug_source(__FILE__, __LINE__);
|
||||
*
|
||||
* @param string file to open
|
||||
* @param integer line number to find
|
||||
* @param integer number of padding lines
|
||||
* @return array
|
||||
*/
|
||||
public static function debug_source($file, $line_number, $padding = 5)
|
||||
{
|
||||
// Make sure we can read the source file
|
||||
if ( ! is_readable($file))
|
||||
return array();
|
||||
|
||||
// Open the file and set the line position
|
||||
$file = fopen($file, 'r');
|
||||
$line = 0;
|
||||
|
||||
// Set the reading range
|
||||
$range = array('start' => $line_number - $padding, 'end' => $line_number + $padding);
|
||||
|
||||
// Set the zero-padding amount for line numbers
|
||||
$format = '% '.strlen($range['end']).'d';
|
||||
|
||||
$source = array();
|
||||
while (($row = fgets($file)) !== FALSE)
|
||||
{
|
||||
// Increment the line number
|
||||
if (++$line > $range['end'])
|
||||
break;
|
||||
|
||||
if ($line >= $range['start'])
|
||||
{
|
||||
$source[sprintf($format, $line)] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the file
|
||||
fclose($file);
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of strings that represent each step in the backtrace.
|
||||
*
|
||||
* @param array trace to analyze
|
||||
* @return array
|
||||
*/
|
||||
public static function trace($trace = NULL)
|
||||
{
|
||||
if ($trace === NULL)
|
||||
{
|
||||
// Start a new trace
|
||||
$trace = debug_backtrace();
|
||||
}
|
||||
|
||||
// Non-standard function calls
|
||||
$statements = array('include', 'include_once', 'require', 'require_once');
|
||||
|
||||
$output = array();
|
||||
foreach ($trace as $step)
|
||||
{
|
||||
if ( ! isset($step['function']))
|
||||
{
|
||||
// Invalid trace step
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($step['file']) AND isset($step['line']))
|
||||
{
|
||||
// Include the source of this step
|
||||
$source = Kohana_Exception::debug_source($step['file'], $step['line']);
|
||||
}
|
||||
|
||||
if (isset($step['file']))
|
||||
{
|
||||
$file = $step['file'];
|
||||
|
||||
if (isset($step['line']))
|
||||
{
|
||||
$line = $step['line'];
|
||||
}
|
||||
}
|
||||
|
||||
// function()
|
||||
$function = $step['function'];
|
||||
|
||||
if (in_array($step['function'], $statements))
|
||||
{
|
||||
if (empty($step['args']))
|
||||
{
|
||||
// No arguments
|
||||
$args = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sanitize the file path
|
||||
$args = array($step['args'][0]);
|
||||
}
|
||||
}
|
||||
elseif (isset($step['args']))
|
||||
{
|
||||
if ($step['function'] === '{closure}')
|
||||
{
|
||||
// Introspection on closures in a stack trace is impossible
|
||||
$params = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($step['class']))
|
||||
{
|
||||
if (method_exists($step['class'], $step['function']))
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], $step['function']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], '__call');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionFunction($step['function']);
|
||||
}
|
||||
|
||||
// Get the function parameters
|
||||
$params = $reflection->getParameters();
|
||||
}
|
||||
|
||||
$args = array();
|
||||
|
||||
foreach ($step['args'] as $i => $arg)
|
||||
{
|
||||
if (isset($params[$i]))
|
||||
{
|
||||
// Assign the argument by the parameter name
|
||||
$args[$params[$i]->name] = $arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assign the argument by number
|
||||
$args[$i] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($step['class']))
|
||||
{
|
||||
// Class->method() or Class::method()
|
||||
$function = $step['class'].$step['type'].$step['function'];
|
||||
}
|
||||
|
||||
$output[] = array(
|
||||
'function' => $function,
|
||||
'args' => isset($args) ? $args : NULL,
|
||||
'file' => isset($file) ? $file : NULL,
|
||||
'line' => isset($line) ? $line : NULL,
|
||||
'source' => isset($source) ? $source : NULL,
|
||||
);
|
||||
|
||||
unset($function, $args, $file, $line, $source);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
} // End Kohana Exception
|
275
web_client/system/helpers/arr.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Array helper class.
|
||||
*
|
||||
* $Id: arr.php 4680 2009-11-10 01:57:00Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class arr_Core {
|
||||
|
||||
/**
|
||||
* Return a callback array from a string, eg: limit[10,20] would become
|
||||
* array('limit', array('10', '20'))
|
||||
*
|
||||
* @param string callback string
|
||||
* @return array
|
||||
*/
|
||||
public static function callback_string($str)
|
||||
{
|
||||
// command[param,param]
|
||||
if (preg_match('/([^\[]*+)\[(.+)\]/', (string) $str, $match))
|
||||
{
|
||||
// command
|
||||
$command = $match[1];
|
||||
|
||||
// param,param
|
||||
$params = preg_split('/(?<!\\\\),/', $match[2]);
|
||||
$params = str_replace('\,', ',', $params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// command
|
||||
$command = $str;
|
||||
|
||||
// No params
|
||||
$params = NULL;
|
||||
}
|
||||
|
||||
return array($command, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates a 2D array clockwise.
|
||||
* Example, turns a 2x3 array into a 3x2 array.
|
||||
*
|
||||
* @param array array to rotate
|
||||
* @param boolean keep the keys in the final rotated array. the sub arrays of the source array need to have the same key values.
|
||||
* if your subkeys might not match, you need to pass FALSE here!
|
||||
* @return array
|
||||
*/
|
||||
public static function rotate($source_array, $keep_keys = TRUE)
|
||||
{
|
||||
$new_array = array();
|
||||
foreach ($source_array as $key => $value)
|
||||
{
|
||||
$value = ($keep_keys === TRUE) ? $value : array_values($value);
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
$new_array[$k][$key] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $new_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from an array and returns the value.
|
||||
*
|
||||
* @param string key to return
|
||||
* @param array array to work on
|
||||
* @return mixed value of the requested array key
|
||||
*/
|
||||
public static function remove($key, & $array)
|
||||
{
|
||||
if ( ! array_key_exists($key, $array))
|
||||
return NULL;
|
||||
|
||||
$val = $array[$key];
|
||||
unset($array[$key]);
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract one or more keys from an array. Each key given after the first
|
||||
* argument (the array) will be extracted. Keys that do not exist in the
|
||||
* search array will be NULL in the extracted data.
|
||||
*
|
||||
* @param array array to search
|
||||
* @param string key name
|
||||
* @return array
|
||||
*/
|
||||
public static function extract(array $search, $keys)
|
||||
{
|
||||
// Get the keys, removing the $search array
|
||||
$keys = array_slice(func_get_args(), 1);
|
||||
|
||||
$found = array();
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$found[$key] = isset($search[$key]) ? $search[$key] : NULL;
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of array[key]. If it doesn't exist, return default.
|
||||
*
|
||||
* @param array array to search
|
||||
* @param string key name
|
||||
* @param mixed default value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get(array $array, $key, $default = NULL)
|
||||
{
|
||||
return isset($array[$key]) ? $array[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because PHP does not have this function.
|
||||
*
|
||||
* @param array array to unshift
|
||||
* @param string key to unshift
|
||||
* @param mixed value to unshift
|
||||
* @return array
|
||||
*/
|
||||
public static function unshift_assoc( array & $array, $key, $val)
|
||||
{
|
||||
$array = array_reverse($array, TRUE);
|
||||
$array[$key] = $val;
|
||||
$array = array_reverse($array, TRUE);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because PHP does not have this function, and array_walk_recursive creates
|
||||
* references in arrays and is not truly recursive.
|
||||
*
|
||||
* @param mixed callback to apply to each member of the array
|
||||
* @param array array to map to
|
||||
* @return array
|
||||
*/
|
||||
public static function map_recursive($callback, array $array)
|
||||
{
|
||||
foreach ($array as $key => $val)
|
||||
{
|
||||
// Map the callback to the key
|
||||
$array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulates array_merge_recursive, but appends numeric keys and replaces
|
||||
* associative keys, instead of appending all keys.
|
||||
*
|
||||
* @param array any number of arrays
|
||||
* @return array
|
||||
*/
|
||||
public static function merge()
|
||||
{
|
||||
$total = func_num_args();
|
||||
|
||||
$result = array();
|
||||
for ($i = 0; $i < $total; $i++)
|
||||
{
|
||||
foreach (func_get_arg($i) as $key => $val)
|
||||
{
|
||||
if (isset($result[$key]))
|
||||
{
|
||||
if (is_array($val))
|
||||
{
|
||||
// Arrays are merged recursively
|
||||
$result[$key] = arr::merge($result[$key], $val);
|
||||
}
|
||||
elseif (is_int($key))
|
||||
{
|
||||
// Indexed arrays are appended
|
||||
array_push($result, $val);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Associative arrays are replaced
|
||||
$result[$key] = $val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// New values are added
|
||||
$result[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites an array with values from input array(s).
|
||||
* Non-existing keys will not be appended!
|
||||
*
|
||||
* @param array key array
|
||||
* @param array input array(s) that will overwrite key array values
|
||||
* @return array
|
||||
*/
|
||||
public static function overwrite($array1, $array2)
|
||||
{
|
||||
foreach (array_intersect_key($array2, $array1) as $key => $value)
|
||||
{
|
||||
$array1[$key] = $value;
|
||||
}
|
||||
|
||||
if (func_num_args() > 2)
|
||||
{
|
||||
foreach (array_slice(func_get_args(), 2) as $array2)
|
||||
{
|
||||
foreach (array_intersect_key($array2, $array1) as $key => $value)
|
||||
{
|
||||
$array1[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $array1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively convert an array to an object.
|
||||
*
|
||||
* @param array array to convert
|
||||
* @return object
|
||||
*/
|
||||
public static function to_object(array $array, $class = 'stdClass')
|
||||
{
|
||||
$object = new $class;
|
||||
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
// Convert the array to an object
|
||||
$value = arr::to_object($value, $class);
|
||||
}
|
||||
|
||||
// Add the value to the object
|
||||
$object->{$key} = $value;
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specific key/column from an array of objects.
|
||||
*
|
||||
* @param string|integer $key The key or column number to pluck from each object.
|
||||
* @param array $array The array of objects to pluck from.
|
||||
* @return array
|
||||
*/
|
||||
public static function pluck($key, $array)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($array as $i => $object)
|
||||
{
|
||||
$result[$i] = isset($object[$key]) ? $object[$key] : NULL;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
} // End arr
|
151
web_client/system/helpers/cookie.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Cookie helper class.
|
||||
*
|
||||
* $Id: cookie.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class cookie_Core {
|
||||
|
||||
/**
|
||||
* Sets a cookie with the given parameters.
|
||||
*
|
||||
* @param string cookie name or array of config options
|
||||
* @param string cookie value
|
||||
* @param integer number of seconds before the cookie expires
|
||||
* @param string URL path to allow
|
||||
* @param string URL domain to allow
|
||||
* @param boolean HTTPS only
|
||||
* @param boolean HTTP only (requires PHP 5.2 or higher)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function set($name, $value = NULL, $expire = NULL, $path = NULL, $domain = NULL, $secure = NULL, $httponly = NULL)
|
||||
{
|
||||
if (headers_sent())
|
||||
return FALSE;
|
||||
|
||||
// If the name param is an array, we import it
|
||||
is_array($name) and extract($name, EXTR_OVERWRITE);
|
||||
|
||||
// Fetch default options
|
||||
$config = Kohana::config('cookie');
|
||||
|
||||
foreach (array('value', 'expire', 'domain', 'path', 'secure', 'httponly') as $item)
|
||||
{
|
||||
if ($$item === NULL AND isset($config[$item]))
|
||||
{
|
||||
$$item = $config[$item];
|
||||
}
|
||||
}
|
||||
|
||||
if ($expire !== 0)
|
||||
{
|
||||
// The expiration is expected to be a UNIX timestamp
|
||||
$expire += time();
|
||||
}
|
||||
|
||||
$value = cookie::salt($name, $value).'~'.$value;
|
||||
|
||||
return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a cookie value, using the Input library.
|
||||
*
|
||||
* @param string cookie name
|
||||
* @param mixed default value
|
||||
* @param boolean use XSS cleaning on the value
|
||||
* @return string
|
||||
*/
|
||||
public static function get($name = NULL, $default = NULL, $xss_clean = FALSE)
|
||||
{
|
||||
// Return an array of all the cookies if we don't have a name
|
||||
if ($name === NULL)
|
||||
{
|
||||
$cookies = array();
|
||||
|
||||
foreach($_COOKIE AS $key => $value)
|
||||
{
|
||||
$cookies[$key] = cookie::get($key, $default, $xss_clean);
|
||||
}
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
if ( ! isset($_COOKIE[$name]))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Get the cookie value
|
||||
$cookie = $_COOKIE[$name];
|
||||
|
||||
// Find the position of the split between salt and contents
|
||||
$split = strlen(cookie::salt($name, NULL));
|
||||
|
||||
if (isset($cookie[$split]) AND $cookie[$split] === '~')
|
||||
{
|
||||
// Separate the salt and the value
|
||||
list ($hash, $value) = explode('~', $cookie, 2);
|
||||
|
||||
if (cookie::salt($name, $value) === $hash)
|
||||
{
|
||||
if ($xss_clean === TRUE AND Kohana::config('core.global_xss_filtering') === FALSE)
|
||||
{
|
||||
return Input::instance()->xss_clean($value);
|
||||
}
|
||||
// Cookie signature is valid
|
||||
return $value;
|
||||
}
|
||||
|
||||
// The cookie signature is invalid, delete it
|
||||
cookie::delete($name);
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nullify and unset a cookie.
|
||||
*
|
||||
* @param string cookie name
|
||||
* @param string URL path
|
||||
* @param string URL domain
|
||||
* @return boolean
|
||||
*/
|
||||
public static function delete($name, $path = NULL, $domain = NULL)
|
||||
{
|
||||
// Delete the cookie from globals
|
||||
unset($_COOKIE[$name]);
|
||||
|
||||
// Sets the cookie value to an empty string, and the expiration to 24 hours ago
|
||||
return cookie::set($name, '', -86400, $path, $domain, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a salt string for a cookie based on the name and value.
|
||||
*
|
||||
* @param string $name name of cookie
|
||||
* @param string $value value of cookie
|
||||
* @return string sha1 hash
|
||||
*/
|
||||
public static function salt($name, $value)
|
||||
{
|
||||
// Determine the user agent
|
||||
$agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : 'unknown';
|
||||
|
||||
// Cookie salt.
|
||||
$salt = Kohana::config('cookie.salt');
|
||||
|
||||
return sha1($agent.$name.$value.$salt);
|
||||
}
|
||||
|
||||
final private function __construct()
|
||||
{
|
||||
// Static class.
|
||||
}
|
||||
|
||||
} // End cookie
|
397
web_client/system/helpers/date.php
Normal file
@ -0,0 +1,397 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Date helper class.
|
||||
*
|
||||
* $Id: date.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class date_Core {
|
||||
|
||||
/**
|
||||
* Converts a UNIX timestamp to DOS format.
|
||||
*
|
||||
* @param integer UNIX timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function unix2dos($timestamp = FALSE)
|
||||
{
|
||||
$timestamp = ($timestamp === FALSE) ? getdate() : getdate($timestamp);
|
||||
|
||||
if ($timestamp['year'] < 1980)
|
||||
{
|
||||
return (1 << 21 | 1 << 16);
|
||||
}
|
||||
|
||||
$timestamp['year'] -= 1980;
|
||||
|
||||
// What voodoo is this? I have no idea... Geert can explain it though,
|
||||
// and that's good enough for me.
|
||||
return ($timestamp['year'] << 25 | $timestamp['mon'] << 21 |
|
||||
$timestamp['mday'] << 16 | $timestamp['hours'] << 11 |
|
||||
$timestamp['minutes'] << 5 | $timestamp['seconds'] >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DOS timestamp to UNIX format.
|
||||
*
|
||||
* @param integer DOS timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function dos2unix($timestamp = FALSE)
|
||||
{
|
||||
$sec = 2 * ($timestamp & 0x1f);
|
||||
$min = ($timestamp >> 5) & 0x3f;
|
||||
$hrs = ($timestamp >> 11) & 0x1f;
|
||||
$day = ($timestamp >> 16) & 0x1f;
|
||||
$mon = ($timestamp >> 21) & 0x0f;
|
||||
$year = ($timestamp >> 25) & 0x7f;
|
||||
|
||||
return mktime($hrs, $min, $sec, $mon, $day, $year + 1980);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset (in seconds) between two time zones.
|
||||
* @see http://php.net/timezones
|
||||
*
|
||||
* @param string timezone to find the offset of
|
||||
* @param string|boolean timezone used as the baseline
|
||||
* @param string time at which to calculate
|
||||
* @return integer
|
||||
*/
|
||||
public static function offset($remote, $local = TRUE, $when = 'now')
|
||||
{
|
||||
if ($local === TRUE)
|
||||
{
|
||||
$local = date_default_timezone_get();
|
||||
}
|
||||
|
||||
// Create timezone objects
|
||||
$remote = new DateTimeZone($remote);
|
||||
$local = new DateTimeZone($local);
|
||||
|
||||
// Create date objects from timezones
|
||||
$time_there = new DateTime($when, $remote);
|
||||
$time_here = new DateTime($when, $local);
|
||||
|
||||
// Find the offset
|
||||
return $remote->getOffset($time_there) - $local->getOffset($time_here);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of seconds in a minute, incrementing by a step.
|
||||
*
|
||||
* @param integer amount to increment each step by, 1 to 30
|
||||
* @param integer start value
|
||||
* @param integer end value
|
||||
* @return array A mirrored (foo => foo) array from 1-60.
|
||||
*/
|
||||
public static function seconds($step = 1, $start = 0, $end = 60)
|
||||
{
|
||||
// Always integer
|
||||
$step = (int) $step;
|
||||
|
||||
$seconds = array();
|
||||
|
||||
for ($i = $start; $i < $end; $i += $step)
|
||||
{
|
||||
$seconds[$i] = ($i < 10) ? '0'.$i : $i;
|
||||
}
|
||||
|
||||
return $seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of minutes in an hour, incrementing by a step.
|
||||
*
|
||||
* @param integer amount to increment each step by, 1 to 30
|
||||
* @return array A mirrored (foo => foo) array from 1-60.
|
||||
*/
|
||||
public static function minutes($step = 5)
|
||||
{
|
||||
// Because there are the same number of minutes as seconds in this set,
|
||||
// we choose to re-use seconds(), rather than creating an entirely new
|
||||
// function. Shhhh, it's cheating! ;) There are several more of these
|
||||
// in the following methods.
|
||||
return date::seconds($step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of hours in a day.
|
||||
*
|
||||
* @param integer amount to increment each step by
|
||||
* @param boolean use 24-hour time
|
||||
* @param integer the hour to start at
|
||||
* @return array A mirrored (foo => foo) array from start-12 or start-23.
|
||||
*/
|
||||
public static function hours($step = 1, $long = FALSE, $start = NULL)
|
||||
{
|
||||
// Default values
|
||||
$step = (int) $step;
|
||||
$long = (bool) $long;
|
||||
$hours = array();
|
||||
|
||||
// Set the default start if none was specified.
|
||||
if ($start === NULL)
|
||||
{
|
||||
$start = ($long === FALSE) ? 1 : 0;
|
||||
}
|
||||
|
||||
$hours = array();
|
||||
|
||||
// 24-hour time has 24 hours, instead of 12
|
||||
$size = ($long === TRUE) ? 23 : 12;
|
||||
|
||||
for ($i = $start; $i <= $size; $i += $step)
|
||||
{
|
||||
$hours[$i] = $i;
|
||||
}
|
||||
|
||||
return $hours;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns AM or PM, based on a given hour.
|
||||
*
|
||||
* @param integer number of the hour
|
||||
* @return string
|
||||
*/
|
||||
public static function ampm($hour)
|
||||
{
|
||||
// Always integer
|
||||
$hour = (int) $hour;
|
||||
|
||||
return ($hour > 11) ? 'PM' : 'AM';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts a non-24-hour number into a 24-hour number.
|
||||
*
|
||||
* @param integer hour to adjust
|
||||
* @param string AM or PM
|
||||
* @return string
|
||||
*/
|
||||
public static function adjust($hour, $ampm)
|
||||
{
|
||||
$hour = (int) $hour;
|
||||
$ampm = strtolower($ampm);
|
||||
|
||||
switch ($ampm)
|
||||
{
|
||||
case 'am':
|
||||
if ($hour == 12)
|
||||
$hour = 0;
|
||||
break;
|
||||
case 'pm':
|
||||
if ($hour < 12)
|
||||
$hour += 12;
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf('%02s', $hour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of days in month.
|
||||
*
|
||||
* @param integer number of month
|
||||
* @param integer number of year to check month, defaults to the current year
|
||||
* @return array A mirrored (foo => foo) array of the days.
|
||||
*/
|
||||
public static function days($month, $year = FALSE)
|
||||
{
|
||||
static $months;
|
||||
|
||||
// Always integers
|
||||
$month = (int) $month;
|
||||
$year = (int) $year;
|
||||
|
||||
// Use the current year by default
|
||||
$year = ($year == FALSE) ? date('Y') : $year;
|
||||
|
||||
// We use caching for months, because time functions are used
|
||||
if (empty($months[$year][$month]))
|
||||
{
|
||||
$months[$year][$month] = array();
|
||||
|
||||
// Use date to find the number of days in the given month
|
||||
$total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1;
|
||||
|
||||
for ($i = 1; $i < $total; $i++)
|
||||
{
|
||||
$months[$year][$month][$i] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $months[$year][$month];
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of months in a year
|
||||
*
|
||||
* @return array A mirrored (foo => foo) array from 1-12.
|
||||
*/
|
||||
public static function months()
|
||||
{
|
||||
return date::hours();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of years between a starting and ending year.
|
||||
* Uses the current year +/- 5 as the max/min.
|
||||
*
|
||||
* @param integer starting year
|
||||
* @param integer ending year
|
||||
* @return array
|
||||
*/
|
||||
public static function years($start = FALSE, $end = FALSE)
|
||||
{
|
||||
// Default values
|
||||
$start = ($start === FALSE) ? date('Y') - 5 : (int) $start;
|
||||
$end = ($end === FALSE) ? date('Y') + 5 : (int) $end;
|
||||
|
||||
$years = array();
|
||||
|
||||
// Add one, so that "less than" works
|
||||
$end += 1;
|
||||
|
||||
for ($i = $start; $i < $end; $i++)
|
||||
{
|
||||
$years[$i] = $i;
|
||||
}
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time difference between two timestamps, in human readable format.
|
||||
*
|
||||
* @param integer timestamp
|
||||
* @param integer timestamp, defaults to the current time
|
||||
* @param string formatting string
|
||||
* @return string|array
|
||||
*/
|
||||
public static function timespan($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
|
||||
{
|
||||
// Array with the output formats
|
||||
$output = preg_split('/[^a-z]+/', strtolower((string) $output));
|
||||
|
||||
// Invalid output
|
||||
if (empty($output))
|
||||
return FALSE;
|
||||
|
||||
// Make the output values into keys
|
||||
extract(array_flip($output), EXTR_SKIP);
|
||||
|
||||
// Default values
|
||||
$time1 = max(0, (int) $time1);
|
||||
$time2 = empty($time2) ? time() : max(0, (int) $time2);
|
||||
|
||||
// Calculate timespan (seconds)
|
||||
$timespan = abs($time1 - $time2);
|
||||
|
||||
// All values found using Google Calculator.
|
||||
// Years and months do not match the formula exactly, due to leap years.
|
||||
|
||||
// Years ago, 60 * 60 * 24 * 365
|
||||
isset($years) and $timespan -= 31556926 * ($years = (int) floor($timespan / 31556926));
|
||||
|
||||
// Months ago, 60 * 60 * 24 * 30
|
||||
isset($months) and $timespan -= 2629744 * ($months = (int) floor($timespan / 2629743.83));
|
||||
|
||||
// Weeks ago, 60 * 60 * 24 * 7
|
||||
isset($weeks) and $timespan -= 604800 * ($weeks = (int) floor($timespan / 604800));
|
||||
|
||||
// Days ago, 60 * 60 * 24
|
||||
isset($days) and $timespan -= 86400 * ($days = (int) floor($timespan / 86400));
|
||||
|
||||
// Hours ago, 60 * 60
|
||||
isset($hours) and $timespan -= 3600 * ($hours = (int) floor($timespan / 3600));
|
||||
|
||||
// Minutes ago, 60
|
||||
isset($minutes) and $timespan -= 60 * ($minutes = (int) floor($timespan / 60));
|
||||
|
||||
// Seconds ago, 1
|
||||
isset($seconds) and $seconds = $timespan;
|
||||
|
||||
// Remove the variables that cannot be accessed
|
||||
unset($timespan, $time1, $time2);
|
||||
|
||||
// Deny access to these variables
|
||||
$deny = array_flip(array('deny', 'key', 'difference', 'output'));
|
||||
|
||||
// Return the difference
|
||||
$difference = array();
|
||||
foreach ($output as $key)
|
||||
{
|
||||
if (isset($$key) AND ! isset($deny[$key]))
|
||||
{
|
||||
// Add requested key to the output
|
||||
$difference[$key] = $$key;
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid output formats string
|
||||
if (empty($difference))
|
||||
return FALSE;
|
||||
|
||||
// If only one output format was asked, don't put it in an array
|
||||
if (count($difference) === 1)
|
||||
return current($difference);
|
||||
|
||||
// Return array
|
||||
return $difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time difference between two timestamps, in the format:
|
||||
* N year, N months, N weeks, N days, N hours, N minutes, and N seconds ago
|
||||
*
|
||||
* @param integer timestamp
|
||||
* @param integer timestamp, defaults to the current time
|
||||
* @param string formatting string
|
||||
* @return string
|
||||
*/
|
||||
public static function timespan_string($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
|
||||
{
|
||||
if ($difference = date::timespan($time1, $time2, $output) AND is_array($difference))
|
||||
{
|
||||
// Determine the key of the last item in the array
|
||||
$last = end($difference);
|
||||
$last = key($difference);
|
||||
|
||||
$span = array();
|
||||
foreach ($difference as $name => $amount)
|
||||
{
|
||||
if ($amount === 0)
|
||||
{
|
||||
// Skip empty amounts
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the amount to the span
|
||||
$span[] = ($name === $last ? ' and ' : ', ').$amount.' '.($amount === 1 ? inflector::singular($name) : $name);
|
||||
}
|
||||
|
||||
// If the difference is less than 60 seconds, remove the preceding and.
|
||||
if (count($span) === 1)
|
||||
{
|
||||
$span[0] = ltrim($span[0], 'and ');
|
||||
}
|
||||
|
||||
// Replace difference by making the span into a string
|
||||
$difference = trim(implode('', $span), ',');
|
||||
}
|
||||
elseif (is_int($difference))
|
||||
{
|
||||
// Single-value return
|
||||
$difference = $difference.' '.($difference === 1 ? inflector::singular($output) : $output);
|
||||
}
|
||||
|
||||
return $difference;
|
||||
}
|
||||
|
||||
} // End date
|
49
web_client/system/helpers/db.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Database helper class.
|
||||
*
|
||||
* $Id: $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class db_Core {
|
||||
|
||||
public static function query($sql)
|
||||
{
|
||||
return new Database_Query($sql);
|
||||
}
|
||||
|
||||
public static function build($database = 'default')
|
||||
{
|
||||
return new Database_Builder($database);
|
||||
}
|
||||
|
||||
public static function select($columns = NULL)
|
||||
{
|
||||
return db::build()->select($columns);
|
||||
}
|
||||
|
||||
public static function insert($table = NULL, $set = NULL)
|
||||
{
|
||||
return db::build()->insert($table, $set);
|
||||
}
|
||||
|
||||
public static function update($table = NULL, $set = NULL, $where = NULL)
|
||||
{
|
||||
return db::build()->update($table, $set, $where);
|
||||
}
|
||||
|
||||
public static function delete($table = NULL, $where = NULL)
|
||||
{
|
||||
return db::build()->delete($table, $where);
|
||||
}
|
||||
|
||||
public static function expr($expression)
|
||||
{
|
||||
return new Database_Expression($expression);
|
||||
}
|
||||
|
||||
} // End db
|
137
web_client/system/helpers/download.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Download helper class.
|
||||
*
|
||||
* $Id: download.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class download_Core {
|
||||
|
||||
/**
|
||||
* Send headers necessary to invoke a "Save As" dialog
|
||||
*
|
||||
* @link http://support.microsoft.com/kb/260519
|
||||
* @link http://greenbytes.de/tech/tc2231/
|
||||
*
|
||||
* @param string file name
|
||||
* @return string file name as it was sent
|
||||
*/
|
||||
public static function dialog($filename)
|
||||
{
|
||||
$filename = basename($filename);
|
||||
|
||||
header('Content-Disposition: attachment; filename="'.$filename.'"');
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the contents of a file or a data string with the proper MIME type and exit.
|
||||
*
|
||||
* @uses exit()
|
||||
* @uses Kohana::close_buffers()
|
||||
*
|
||||
* @param string a file path or file name
|
||||
* @param string optional data to send
|
||||
* @return void
|
||||
*/
|
||||
public static function send($filename, $data = NULL)
|
||||
{
|
||||
if ($data === NULL)
|
||||
{
|
||||
$filepath = realpath($filename);
|
||||
|
||||
$filename = basename($filepath);
|
||||
$filesize = filesize($filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
$filename = basename($filename);
|
||||
$filesize = strlen($data);
|
||||
}
|
||||
|
||||
// Retrieve MIME type by extension
|
||||
$mime = Kohana::config('mimes.'.strtolower(substr(strrchr($filename, '.'), 1)));
|
||||
$mime = empty($mime) ? 'application/octet-stream' : $mime[0];
|
||||
|
||||
// Close output buffers
|
||||
Kohana::close_buffers(FALSE);
|
||||
|
||||
// Clear any output
|
||||
Event::add('system.display', create_function('', 'Kohana::$output = "";'));
|
||||
|
||||
// Send headers
|
||||
header("Content-Type: $mime");
|
||||
header('Content-Length: '.sprintf('%d', $filesize));
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
// Send data
|
||||
if ($data === NULL)
|
||||
{
|
||||
$handle = fopen($filepath, 'rb');
|
||||
|
||||
fpassthru($handle);
|
||||
fclose($handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $data;
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the download of a file by the user's browser by preventing any
|
||||
* caching. Contains a workaround for Internet Explorer.
|
||||
*
|
||||
* @link http://support.microsoft.com/kb/316431
|
||||
* @link http://support.microsoft.com/kb/812935
|
||||
*
|
||||
* @uses download::dialog()
|
||||
* @uses download::send()
|
||||
*
|
||||
* @param string a file path or file name
|
||||
* @param mixed data to be sent if the filename does not exist
|
||||
* @param string suggested filename to display in the download
|
||||
* @return void
|
||||
*/
|
||||
public static function force($filename = NULL, $data = NULL, $nicename = NULL)
|
||||
{
|
||||
download::dialog(empty($nicename) ? $filename : $nicename);
|
||||
|
||||
// Prevent caching
|
||||
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
|
||||
|
||||
if (request::user_agent('browser') === 'Internet Explorer' AND request::user_agent('version') <= '6.0')
|
||||
{
|
||||
// HTTP 1.0
|
||||
header('Pragma:');
|
||||
|
||||
// HTTP 1.1 with IE extensions
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
}
|
||||
else
|
||||
{
|
||||
// HTTP 1.0
|
||||
header('Pragma: no-cache');
|
||||
|
||||
// HTTP 1.1
|
||||
header('Cache-Control: no-cache, max-age=0');
|
||||
}
|
||||
|
||||
if (is_file($filename))
|
||||
{
|
||||
download::send($filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
download::send($filename, $data);
|
||||
}
|
||||
}
|
||||
|
||||
} // End download
|
120
web_client/system/helpers/expires.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Controls headers that effect client caching of pages
|
||||
*
|
||||
* $Id: expires.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class expires_Core {
|
||||
|
||||
/**
|
||||
* Sets the amount of time before content expires
|
||||
*
|
||||
* @param integer Seconds before the content expires
|
||||
* @return integer Timestamp when the content expires
|
||||
*/
|
||||
public static function set($seconds = 60)
|
||||
{
|
||||
$now = time();
|
||||
$expires = $now + $seconds;
|
||||
|
||||
header('Last-Modified: '.gmdate('D, d M Y H:i:s T', $now));
|
||||
|
||||
// HTTP 1.0
|
||||
header('Expires: '.gmdate('D, d M Y H:i:s T', $expires));
|
||||
|
||||
// HTTP 1.1
|
||||
header('Cache-Control: max-age='.$seconds);
|
||||
|
||||
return $expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the If-Modified-Since header
|
||||
*
|
||||
* @return integer|boolean Timestamp or FALSE when header is lacking or malformed
|
||||
*/
|
||||
public static function get()
|
||||
{
|
||||
if ( ! empty($_SERVER['HTTP_IF_MODIFIED_SINCE']))
|
||||
{
|
||||
// Some versions of IE6 append "; length=####"
|
||||
if (($strpos = strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], ';')) !== FALSE)
|
||||
{
|
||||
$mod_time = substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, $strpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
$mod_time = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
|
||||
}
|
||||
|
||||
return strtotime($mod_time);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if content should be updated otherwise sends Not Modified status
|
||||
* and exits.
|
||||
*
|
||||
* @uses exit()
|
||||
* @uses expires::get()
|
||||
*
|
||||
* @param integer Maximum age of the content in seconds
|
||||
* @return integer|boolean Timestamp of the If-Modified-Since header or FALSE when header is lacking or malformed
|
||||
*/
|
||||
public static function check($seconds = 60)
|
||||
{
|
||||
if ($last_modified = expires::get())
|
||||
{
|
||||
$expires = $last_modified + $seconds;
|
||||
$max_age = $expires - time();
|
||||
|
||||
if ($max_age > 0)
|
||||
{
|
||||
// Content has not expired
|
||||
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
|
||||
header('Last-Modified: '.gmdate('D, d M Y H:i:s T', $last_modified));
|
||||
|
||||
// HTTP 1.0
|
||||
header('Expires: '.gmdate('D, d M Y H:i:s T', $expires));
|
||||
|
||||
// HTTP 1.1
|
||||
header('Cache-Control: max-age='.$max_age);
|
||||
|
||||
// Clear any output
|
||||
Event::add('system.display', create_function('', 'Kohana::$output = "";'));
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
return $last_modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if expiration headers are already set
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function headers_set()
|
||||
{
|
||||
foreach (headers_list() as $header)
|
||||
{
|
||||
if (strncasecmp($header, 'Expires:', 8) === 0
|
||||
OR strncasecmp($header, 'Cache-Control:', 14) === 0
|
||||
OR strncasecmp($header, 'Last-Modified:', 14) === 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} // End expires
|
122
web_client/system/helpers/feed.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Feed helper class.
|
||||
*
|
||||
* $Id: feed.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class feed_Core {
|
||||
|
||||
/**
|
||||
* Parses a remote feed into an array.
|
||||
*
|
||||
* @param string remote feed URL
|
||||
* @param integer item limit to fetch
|
||||
* @return array
|
||||
*/
|
||||
public static function parse($feed, $limit = 0)
|
||||
{
|
||||
// Check if SimpleXML is installed
|
||||
if( ! function_exists('simplexml_load_file'))
|
||||
throw new Kohana_User_Exception('Feed Error', 'SimpleXML must be installed!');
|
||||
|
||||
// Make limit an integer
|
||||
$limit = (int) $limit;
|
||||
|
||||
// Disable error reporting while opening the feed
|
||||
$ER = error_reporting(0);
|
||||
|
||||
// Allow loading by filename or raw XML string
|
||||
$load = (is_file($feed) OR valid::url($feed)) ? 'simplexml_load_file' : 'simplexml_load_string';
|
||||
|
||||
// Load the feed
|
||||
$feed = $load($feed, 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
|
||||
// Restore error reporting
|
||||
error_reporting($ER);
|
||||
|
||||
// Feed could not be loaded
|
||||
if ($feed === FALSE)
|
||||
return array();
|
||||
|
||||
// Detect the feed type. RSS 1.0/2.0 and Atom 1.0 are supported.
|
||||
$feed = isset($feed->channel) ? $feed->xpath('//item') : $feed->entry;
|
||||
|
||||
$i = 0;
|
||||
$items = array();
|
||||
|
||||
foreach ($feed as $item)
|
||||
{
|
||||
if ($limit > 0 AND $i++ === $limit)
|
||||
break;
|
||||
|
||||
$items[] = (array) $item;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feed from the given parameters.
|
||||
*
|
||||
* @param array feed information
|
||||
* @param array items to add to the feed
|
||||
* @param string define which format to use
|
||||
* @param string define which encoding to use
|
||||
* @return string
|
||||
*/
|
||||
public static function create($info, $items, $format = 'rss2', $encoding = 'UTF-8')
|
||||
{
|
||||
$info += array('title' => 'Generated Feed', 'link' => '', 'generator' => 'KohanaPHP');
|
||||
|
||||
$feed = '<?xml version="1.0" encoding="'.$encoding.'"?><rss version="2.0"><channel></channel></rss>';
|
||||
$feed = simplexml_load_string($feed);
|
||||
|
||||
foreach ($info as $name => $value)
|
||||
{
|
||||
if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value)))
|
||||
{
|
||||
// Convert timestamps to RFC 822 formatted dates
|
||||
$value = date(DATE_RFC822, $value);
|
||||
}
|
||||
elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value = url::site($value, 'http');
|
||||
}
|
||||
|
||||
// Add the info to the channel
|
||||
$feed->channel->addChild($name, $value);
|
||||
}
|
||||
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// Add the item to the channel
|
||||
$row = $feed->channel->addChild('item');
|
||||
|
||||
foreach ($item as $name => $value)
|
||||
{
|
||||
if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value)))
|
||||
{
|
||||
// Convert timestamps to RFC 822 formatted dates
|
||||
$value = date(DATE_RFC822, $value);
|
||||
}
|
||||
elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value = url::site($value, 'http');
|
||||
}
|
||||
|
||||
// Add the info to the row
|
||||
$row->addChild($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $feed->asXML();
|
||||
}
|
||||
|
||||
} // End feed
|
186
web_client/system/helpers/file.php
Normal file
@ -0,0 +1,186 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* File helper class.
|
||||
*
|
||||
* $Id: file.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class file_Core {
|
||||
|
||||
/**
|
||||
* Attempt to get the mime type from a file. This method is horribly
|
||||
* unreliable, due to PHP being horribly unreliable when it comes to
|
||||
* determining the mime-type of a file.
|
||||
*
|
||||
* @param string filename
|
||||
* @return string mime-type, if found
|
||||
* @return boolean FALSE, if not found
|
||||
*/
|
||||
public static function mime($filename)
|
||||
{
|
||||
// Make sure the file is readable
|
||||
if ( ! (is_file($filename) AND is_readable($filename)))
|
||||
return FALSE;
|
||||
|
||||
// Get the extension from the filename
|
||||
$extension = strtolower(substr(strrchr($filename, '.'), 1));
|
||||
|
||||
if (preg_match('/^(?:jpe?g|png|[gt]if|bmp|swf)$/', $extension))
|
||||
{
|
||||
// Disable error reporting
|
||||
$ER = error_reporting(0);
|
||||
|
||||
// Use getimagesize() to find the mime type on images
|
||||
$mime = getimagesize($filename);
|
||||
|
||||
// Turn error reporting back on
|
||||
error_reporting($ER);
|
||||
|
||||
// Return the mime type
|
||||
if (isset($mime['mime']))
|
||||
return $mime['mime'];
|
||||
}
|
||||
|
||||
if (function_exists('finfo_open'))
|
||||
{
|
||||
// Use the fileinfo extension
|
||||
$finfo = finfo_open(FILEINFO_MIME);
|
||||
$mime = finfo_file($finfo, $filename);
|
||||
finfo_close($finfo);
|
||||
|
||||
// Return the mime type
|
||||
return $mime;
|
||||
}
|
||||
|
||||
if (ini_get('mime_magic.magicfile') AND function_exists('mime_content_type'))
|
||||
{
|
||||
// Return the mime type using mime_content_type
|
||||
return mime_content_type($filename);
|
||||
}
|
||||
|
||||
if ( ! KOHANA_IS_WIN)
|
||||
{
|
||||
// Attempt to locate use the file command, checking the return value
|
||||
if ($command = trim(exec('which file', $output, $return)) AND $return === 0)
|
||||
{
|
||||
return trim(exec($command.' -bi '.escapeshellarg($filename)));
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($extension) AND is_array($mime = Kohana::config('mimes.'.$extension)))
|
||||
{
|
||||
// Return the mime-type guess, based on the extension
|
||||
return $mime[0];
|
||||
}
|
||||
|
||||
// Unable to find the mime-type
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a file into pieces matching a specific size.
|
||||
*
|
||||
* @param string file to be split
|
||||
* @param string directory to output to, defaults to the same directory as the file
|
||||
* @param integer size, in MB, for each chunk to be
|
||||
* @return integer The number of pieces that were created.
|
||||
*/
|
||||
public static function split($filename, $output_dir = FALSE, $piece_size = 10)
|
||||
{
|
||||
// Find output dir
|
||||
$output_dir = ($output_dir == FALSE) ? pathinfo(str_replace('\\', '/', realpath($filename)), PATHINFO_DIRNAME) : str_replace('\\', '/', realpath($output_dir));
|
||||
$output_dir = rtrim($output_dir, '/').'/';
|
||||
|
||||
// Open files for writing
|
||||
$input_file = fopen($filename, 'rb');
|
||||
|
||||
// Change the piece size to bytes
|
||||
$piece_size = 1024 * 1024 * (int) $piece_size; // Size in bytes
|
||||
|
||||
// Set up reading variables
|
||||
$read = 0; // Number of bytes read
|
||||
$piece = 1; // Current piece
|
||||
$chunk = 1024 * 8; // Chunk size to read
|
||||
|
||||
// Split the file
|
||||
while ( ! feof($input_file))
|
||||
{
|
||||
// Open a new piece
|
||||
$piece_name = $filename.'.'.str_pad($piece, 3, '0', STR_PAD_LEFT);
|
||||
$piece_open = @fopen($piece_name, 'wb+') or die('Could not write piece '.$piece_name);
|
||||
|
||||
// Fill the current piece
|
||||
while ($read < $piece_size AND $data = fread($input_file, $chunk))
|
||||
{
|
||||
fwrite($piece_open, $data) or die('Could not write to open piece '.$piece_name);
|
||||
$read += $chunk;
|
||||
}
|
||||
|
||||
// Close the current piece
|
||||
fclose($piece_open);
|
||||
|
||||
// Prepare to open a new piece
|
||||
$read = 0;
|
||||
$piece++;
|
||||
|
||||
// Make sure that piece is valid
|
||||
($piece < 999) or die('Maximum of 999 pieces exceeded, try a larger piece size');
|
||||
}
|
||||
|
||||
// Close input file
|
||||
fclose($input_file);
|
||||
|
||||
// Returns the number of pieces that were created
|
||||
return ($piece - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a split file into a whole file.
|
||||
*
|
||||
* @param string split filename, without .000 extension
|
||||
* @param string output filename, if different then an the filename
|
||||
* @return integer The number of pieces that were joined.
|
||||
*/
|
||||
public static function join($filename, $output = FALSE)
|
||||
{
|
||||
if ($output == FALSE)
|
||||
$output = $filename;
|
||||
|
||||
// Set up reading variables
|
||||
$piece = 1; // Current piece
|
||||
$chunk = 1024 * 8; // Chunk size to read
|
||||
|
||||
// Open output file
|
||||
$output_file = @fopen($output, 'wb+') or die('Could not open output file '.$output);
|
||||
|
||||
// Read each piece
|
||||
while ($piece_open = @fopen(($piece_name = $filename.'.'.str_pad($piece, 3, '0', STR_PAD_LEFT)), 'rb'))
|
||||
{
|
||||
// Write the piece into the output file
|
||||
while ( ! feof($piece_open))
|
||||
{
|
||||
fwrite($output_file, fread($piece_open, $chunk));
|
||||
}
|
||||
|
||||
// Close the current piece
|
||||
fclose($piece_open);
|
||||
|
||||
// Prepare for a new piece
|
||||
$piece++;
|
||||
|
||||
// Make sure piece is valid
|
||||
($piece < 999) or die('Maximum of 999 pieces exceeded');
|
||||
}
|
||||
|
||||
// Close the output file
|
||||
fclose($output_file);
|
||||
|
||||
// Return the number of pieces joined
|
||||
return ($piece - 1);
|
||||
}
|
||||
|
||||
} // End file
|
468
web_client/system/helpers/form.php
Normal file
@ -0,0 +1,468 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Form helper class.
|
||||
*
|
||||
* $Id: form.php 4699 2009-12-08 18:45:14Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class form_Core {
|
||||
|
||||
/**
|
||||
* Generates an opening HTML form tag.
|
||||
*
|
||||
* @param string form action attribute
|
||||
* @param array extra attributes
|
||||
* @param array hidden fields to be created immediately after the form tag
|
||||
* @param string non-default protocol, eg: https
|
||||
* @return string
|
||||
*/
|
||||
public static function open($action = NULL, $attr = array(), $hidden = NULL, $protocol = NULL)
|
||||
{
|
||||
// Make sure that the method is always set
|
||||
empty($attr['method']) and $attr['method'] = 'post';
|
||||
|
||||
if ($attr['method'] !== 'post' AND $attr['method'] !== 'get')
|
||||
{
|
||||
// If the method is invalid, use post
|
||||
$attr['method'] = 'post';
|
||||
}
|
||||
|
||||
if ($action === NULL)
|
||||
{
|
||||
// Use the current URL as the default action
|
||||
$action = url::site(Router::$complete_uri, $protocol);
|
||||
}
|
||||
elseif (strpos($action, '://') === FALSE)
|
||||
{
|
||||
// Make the action URI into a URL
|
||||
$action = url::site($action, $protocol);
|
||||
}
|
||||
|
||||
// Set action
|
||||
$attr['action'] = $action;
|
||||
|
||||
// Form opening tag
|
||||
$form = '<form'.form::attributes($attr).'>'."\n";
|
||||
|
||||
// Add hidden fields immediate after opening tag
|
||||
empty($hidden) or $form .= form::hidden($hidden);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an opening HTML form tag that can be used for uploading files.
|
||||
*
|
||||
* @param string form action attribute
|
||||
* @param array extra attributes
|
||||
* @param array hidden fields to be created immediately after the form tag
|
||||
* @return string
|
||||
*/
|
||||
public static function open_multipart($action = NULL, $attr = array(), $hidden = array())
|
||||
{
|
||||
// Set multi-part form type
|
||||
$attr['enctype'] = 'multipart/form-data';
|
||||
|
||||
return form::open($action, $attr, $hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HTML form hidden input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function hidden($data, $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
$data['type'] = 'hidden';
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form input tag. Defaults to a text type.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function input($data, $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
// Type and value are required attributes
|
||||
$data += array
|
||||
(
|
||||
'type' => 'text',
|
||||
'value' => $value
|
||||
);
|
||||
|
||||
return '<input'.form::attributes($data).' '.$extra.' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HTML form password input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function password($data, $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
$data['type'] = 'password';
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form upload input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function upload($data, $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
$data['type'] = 'file';
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form textarea tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @param boolean encode existing entities
|
||||
* @return string
|
||||
*/
|
||||
public static function textarea($data, $value = '', $extra = '', $double_encode = TRUE)
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
if ( ! isset($data['rows']))
|
||||
{
|
||||
$data['rows'] = '';
|
||||
}
|
||||
|
||||
if ( ! isset($data['cols']))
|
||||
{
|
||||
$data['cols'] = '';
|
||||
}
|
||||
|
||||
// Use the value from $data if possible, or use $value
|
||||
$value = isset($data['value']) ? $data['value'] : $value;
|
||||
|
||||
// Value is not part of the attributes
|
||||
unset($data['value']);
|
||||
|
||||
return '<textarea'.form::attributes($data, 'textarea').' '.$extra.'>'.htmlspecialchars($value, ENT_QUOTES, Kohana::CHARSET, $double_encode).'</textarea>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form select tag, or "dropdown menu".
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param array select options, when using a name
|
||||
* @param string|array option key(s) that should be selected by default
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function dropdown($data, $options = NULL, $selected = NULL, $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($data['options']))
|
||||
{
|
||||
// Use data options
|
||||
$options = $data['options'];
|
||||
}
|
||||
|
||||
if (isset($data['selected']))
|
||||
{
|
||||
// Use data selected
|
||||
$selected = $data['selected'];
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($selected))
|
||||
{
|
||||
// Multi-select box
|
||||
$data['multiple'] = 'multiple';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Single selection (but converted to an array)
|
||||
$selected = array($selected);
|
||||
}
|
||||
|
||||
$input = '<select'.form::attributes($data, 'select').' '.$extra.'>'."\n";
|
||||
foreach ((array) $options as $key => $val)
|
||||
{
|
||||
// Key should always be a string
|
||||
$key = (string) $key;
|
||||
|
||||
if (is_array($val))
|
||||
{
|
||||
$input .= '<optgroup label="'.$key.'">'."\n";
|
||||
foreach ($val as $inner_key => $inner_val)
|
||||
{
|
||||
// Inner key should always be a string
|
||||
$inner_key = (string) $inner_key;
|
||||
|
||||
$sel = in_array($inner_key, $selected) ? ' selected="selected"' : '';
|
||||
$input .= '<option value="'.$inner_key.'"'.$sel.'>'.htmlspecialchars($inner_val, ENT_QUOTES, Kohana::CHARSET).'</option>'."\n";
|
||||
}
|
||||
$input .= '</optgroup>'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sel = in_array($key, $selected) ? ' selected="selected"' : '';
|
||||
$input .= '<option value="'.$key.'"'.$sel.'>'.htmlspecialchars($val, ENT_QUOTES, Kohana::CHARSET).'</option>'."\n";
|
||||
}
|
||||
}
|
||||
$input .= '</select>';
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form checkbox input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param boolean make the checkbox checked by default
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function checkbox($data, $value = '', $checked = FALSE, $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
$data['type'] = 'checkbox';
|
||||
|
||||
if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE))
|
||||
{
|
||||
$data['checked'] = 'checked';
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($data['checked']);
|
||||
}
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form radio input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param boolean make the radio selected by default
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function radio($data = '', $value = '', $checked = FALSE, $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
$data['type'] = 'radio';
|
||||
|
||||
if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE))
|
||||
{
|
||||
$data['checked'] = 'checked';
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($data['checked']);
|
||||
}
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form submit input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function submit($data = '', $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
if (empty($data['name']))
|
||||
{
|
||||
// Remove the name if it is empty
|
||||
unset($data['name']);
|
||||
}
|
||||
|
||||
$data['type'] = 'submit';
|
||||
|
||||
return form::input($data, $value, $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form button input tag.
|
||||
*
|
||||
* @param string|array input name or an array of HTML attributes
|
||||
* @param string input value, when using a name
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function button($data = '', $value = '', $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
$data = array('name' => $data);
|
||||
}
|
||||
|
||||
if (empty($data['name']))
|
||||
{
|
||||
// Remove the name if it is empty
|
||||
unset($data['name']);
|
||||
}
|
||||
|
||||
if (isset($data['value']) AND empty($value))
|
||||
{
|
||||
$value = arr::remove('value', $data);
|
||||
}
|
||||
|
||||
return '<button'.form::attributes($data, 'button').' '.$extra.'>'.$value.'</button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML form label tag.
|
||||
*
|
||||
* @param string|array label "for" name or an array of HTML attributes
|
||||
* @param string label text or HTML
|
||||
* @param string a string to be attached to the end of the attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function label($data = '', $text = NULL, $extra = '')
|
||||
{
|
||||
if ( ! is_array($data))
|
||||
{
|
||||
if (is_string($data))
|
||||
{
|
||||
// Specify the input this label is for
|
||||
$data = array('for' => $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No input specified
|
||||
$data = array();
|
||||
}
|
||||
}
|
||||
|
||||
if ($text === NULL AND isset($data['for']))
|
||||
{
|
||||
// Make the text the human-readable input name
|
||||
$text = ucwords(inflector::humanize($data['for']));
|
||||
}
|
||||
|
||||
return '<label'.form::attributes($data).' '.$extra.'>'.$text.'</label>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts a key/value array of HTML attributes, putting form attributes first,
|
||||
* and returns an attribute string.
|
||||
*
|
||||
* @param array HTML attributes array
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes($attr, $type = NULL)
|
||||
{
|
||||
if (empty($attr))
|
||||
return '';
|
||||
|
||||
$order = array
|
||||
(
|
||||
'action',
|
||||
'method',
|
||||
'type',
|
||||
'id',
|
||||
'name',
|
||||
'value',
|
||||
'src',
|
||||
'size',
|
||||
'maxlength',
|
||||
'rows',
|
||||
'cols',
|
||||
'accept',
|
||||
'tabindex',
|
||||
'accesskey',
|
||||
'align',
|
||||
'alt',
|
||||
'title',
|
||||
'class',
|
||||
'style',
|
||||
'selected',
|
||||
'checked',
|
||||
'readonly',
|
||||
'disabled'
|
||||
);
|
||||
|
||||
$sorted = array();
|
||||
foreach ($order as $key)
|
||||
{
|
||||
if (isset($attr[$key]))
|
||||
{
|
||||
// Move the attribute to the sorted array
|
||||
$sorted[$key] = $attr[$key];
|
||||
|
||||
// Remove the attribute from unsorted array
|
||||
unset($attr[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the sorted and unsorted attributes and create an HTML string
|
||||
return html::attributes(array_merge($sorted, $attr));
|
||||
}
|
||||
|
||||
} // End form
|
114
web_client/system/helpers/format.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Format helper class.
|
||||
*
|
||||
* $Id: format.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class format_Core {
|
||||
|
||||
/**
|
||||
* Formats a number according to the current locale.
|
||||
*
|
||||
* @param float
|
||||
* @param int|boolean number of fractional digits or TRUE to use the locale default
|
||||
* @return string
|
||||
*/
|
||||
public static function number($number, $decimals = 0)
|
||||
{
|
||||
$locale = localeconv();
|
||||
|
||||
if ($decimals === TRUE)
|
||||
return number_format($number, $locale['frac_digits'], $locale['decimal_point'], $locale['thousands_sep']);
|
||||
|
||||
return number_format($number, $decimals, $locale['decimal_point'], $locale['thousands_sep']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a phone number according to the specified format.
|
||||
*
|
||||
* @param string phone number
|
||||
* @param string format string
|
||||
* @return string
|
||||
*/
|
||||
public static function phone($number, $format = '3-3-4')
|
||||
{
|
||||
// Get rid of all non-digit characters in number string
|
||||
$number_clean = preg_replace('/\D+/', '', (string) $number);
|
||||
|
||||
// Array of digits we need for a valid format
|
||||
$format_parts = preg_split('/[^1-9][^0-9]*/', $format, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
// Number must match digit count of a valid format
|
||||
if (strlen($number_clean) !== array_sum($format_parts))
|
||||
return $number;
|
||||
|
||||
// Build regex
|
||||
$regex = '(\d{'.implode('})(\d{', $format_parts).'})';
|
||||
|
||||
// Build replace string
|
||||
for ($i = 1, $c = count($format_parts); $i <= $c; $i++)
|
||||
{
|
||||
$format = preg_replace('/(?<!\$)[1-9][0-9]*/', '\$'.$i, $format, 1);
|
||||
}
|
||||
|
||||
// Hocus pocus!
|
||||
return preg_replace('/^'.$regex.'$/', $format, $number_clean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a URL to contain a protocol at the beginning.
|
||||
*
|
||||
* @param string possibly incomplete URL
|
||||
* @return string
|
||||
*/
|
||||
public static function url($str = '')
|
||||
{
|
||||
// Clear protocol-only strings like "http://"
|
||||
if ($str === '' OR substr($str, -3) === '://')
|
||||
return '';
|
||||
|
||||
// If no protocol given, prepend "http://" by default
|
||||
if (strpos($str, '://') === FALSE)
|
||||
return 'http://'.$str;
|
||||
|
||||
// Return the original URL
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a hexadecimal HTML color value. All values will be converted
|
||||
* to lowercase, have a "#" prepended and contain six characters.
|
||||
*
|
||||
* @param string hexadecimal HTML color value
|
||||
* @return string
|
||||
*/
|
||||
public static function color($str = '')
|
||||
{
|
||||
// Reject invalid values
|
||||
if ( ! valid::color($str))
|
||||
return '';
|
||||
|
||||
// Convert to lowercase
|
||||
$str = strtolower($str);
|
||||
|
||||
// Prepend "#"
|
||||
if ($str[0] !== '#')
|
||||
{
|
||||
$str = '#'.$str;
|
||||
}
|
||||
|
||||
// Expand short notation
|
||||
if (strlen($str) === 4)
|
||||
{
|
||||
$str = '#'.$str[1].$str[1].$str[2].$str[2].$str[3].$str[3];
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
} // End format
|
366
web_client/system/helpers/html.php
Normal file
@ -0,0 +1,366 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* HTML helper class.
|
||||
*
|
||||
* $Id: html.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class html_Core {
|
||||
|
||||
// Enable or disable automatic setting of target="_blank"
|
||||
public static $windowed_urls = FALSE;
|
||||
|
||||
/**
|
||||
* Convert special characters to HTML entities
|
||||
*
|
||||
* @param string string to convert
|
||||
* @param boolean encode existing entities
|
||||
* @return string
|
||||
*/
|
||||
public static function chars($str, $double_encode = TRUE)
|
||||
{
|
||||
// Return HTML entities using the Kohana charset
|
||||
return htmlspecialchars($str, ENT_QUOTES, Kohana::CHARSET, $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create HTML link anchors.
|
||||
*
|
||||
* @param string URL or URI string
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @param string non-default protocol, eg: https
|
||||
* @param boolean option to escape the title that is output
|
||||
* @return string
|
||||
*/
|
||||
public static function anchor($uri, $title = NULL, $attributes = NULL, $protocol = NULL, $escape_title = FALSE)
|
||||
{
|
||||
if ($uri === '')
|
||||
{
|
||||
$site_url = url::base(FALSE);
|
||||
}
|
||||
elseif (strpos($uri, '#') === 0)
|
||||
{
|
||||
// This is an id target link, not a URL
|
||||
$site_url = $uri;
|
||||
}
|
||||
elseif (strpos($uri, '://') === FALSE)
|
||||
{
|
||||
$site_url = url::site($uri, $protocol);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (html::$windowed_urls === TRUE AND empty($attributes['target']))
|
||||
{
|
||||
$attributes['target'] = '_blank';
|
||||
}
|
||||
|
||||
$site_url = $uri;
|
||||
}
|
||||
|
||||
return
|
||||
// Parsed URL
|
||||
'<a href="'.htmlspecialchars($site_url, ENT_QUOTES, Kohana::CHARSET, FALSE).'"'
|
||||
// Attributes empty? Use an empty string
|
||||
.(is_array($attributes) ? html::attributes($attributes) : '').'>'
|
||||
// Title empty? Use the parsed URL
|
||||
.($escape_title ? htmlspecialchars((($title === NULL) ? $site_url : $title), ENT_QUOTES, Kohana::CHARSET, FALSE) : (($title === NULL) ? $site_url : $title)).'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML anchor to a file.
|
||||
*
|
||||
* @param string name of file to link to
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @param string non-default protocol, eg: ftp
|
||||
* @return string
|
||||
*/
|
||||
public static function file_anchor($file, $title = NULL, $attributes = NULL, $protocol = NULL)
|
||||
{
|
||||
return
|
||||
// Base URL + URI = full URL
|
||||
'<a href="'.htmlspecialchars(url::base(FALSE, $protocol).$file, ENT_QUOTES, Kohana::CHARSET, FALSE).'"'
|
||||
// Attributes empty? Use an empty string
|
||||
.(is_array($attributes) ? html::attributes($attributes) : '').'>'
|
||||
// Title empty? Use the filename part of the URI
|
||||
.(($title === NULL) ? end(explode('/', $file)) : $title) .'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an obfuscated version of an email address.
|
||||
*
|
||||
* @param string email address
|
||||
* @return string
|
||||
*/
|
||||
public static function email($email)
|
||||
{
|
||||
$safe = '';
|
||||
foreach (str_split($email) as $letter)
|
||||
{
|
||||
switch (($letter === '@') ? rand(1, 2) : rand(1, 3))
|
||||
{
|
||||
// HTML entity code
|
||||
case 1: $safe .= '&#'.ord($letter).';'; break;
|
||||
// Hex character code
|
||||
case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break;
|
||||
// Raw (no) encoding
|
||||
case 3: $safe .= $letter;
|
||||
}
|
||||
}
|
||||
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an email anchor.
|
||||
*
|
||||
* @param string email address to send to
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function mailto($email, $title = NULL, $attributes = NULL)
|
||||
{
|
||||
if (empty($email))
|
||||
return $title;
|
||||
|
||||
// Remove the subject or other parameters that do not need to be encoded
|
||||
if (strpos($email, '?') !== FALSE)
|
||||
{
|
||||
// Extract the parameters from the email address
|
||||
list ($email, $params) = explode('?', $email, 2);
|
||||
|
||||
// Make the params into a query string, replacing spaces
|
||||
$params = '?'.str_replace(' ', '%20', $params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No parameters
|
||||
$params = '';
|
||||
}
|
||||
|
||||
// Obfuscate email address
|
||||
$safe = html::email($email);
|
||||
|
||||
// Title defaults to the encoded email address
|
||||
empty($title) and $title = $safe;
|
||||
|
||||
// Parse attributes
|
||||
empty($attributes) or $attributes = html::attributes($attributes);
|
||||
|
||||
// Encoded start of the href="" is a static encoded version of 'mailto:'
|
||||
return '<a href="mailto:'.$safe.$params.'"'.$attributes.'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a "breadcrumb" list of anchors representing the URI.
|
||||
*
|
||||
* @param array segments to use as breadcrumbs, defaults to using Router::$segments
|
||||
* @return string
|
||||
*/
|
||||
public static function breadcrumb($segments = NULL)
|
||||
{
|
||||
empty($segments) and $segments = Router::$segments;
|
||||
|
||||
$array = array();
|
||||
while ($segment = array_pop($segments))
|
||||
{
|
||||
$array[] = html::anchor
|
||||
(
|
||||
// Complete URI for the URL
|
||||
implode('/', $segments).'/'.$segment,
|
||||
// Title for the current segment
|
||||
ucwords(inflector::humanize($segment))
|
||||
);
|
||||
}
|
||||
|
||||
// Retrun the array of all the segments
|
||||
return array_reverse($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a meta tag.
|
||||
*
|
||||
* @param string|array tag name, or an array of tags
|
||||
* @param string tag "content" value
|
||||
* @return string
|
||||
*/
|
||||
public static function meta($tag, $value = NULL)
|
||||
{
|
||||
if (is_array($tag))
|
||||
{
|
||||
$tags = array();
|
||||
foreach ($tag as $t => $v)
|
||||
{
|
||||
// Build each tag and add it to the array
|
||||
$tags[] = html::meta($t, $v);
|
||||
}
|
||||
|
||||
// Return all of the tags as a string
|
||||
return implode("\n", $tags);
|
||||
}
|
||||
|
||||
// Set the meta attribute value
|
||||
$attr = in_array(strtolower($tag), Kohana::config('http.meta_equiv')) ? 'http-equiv' : 'name';
|
||||
|
||||
return '<meta '.$attr.'="'.$tag.'" content="'.$value.'" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a stylesheet link.
|
||||
*
|
||||
* @param string|array filename, or array of filenames to match to array of medias
|
||||
* @param string|array media type of stylesheet, or array to match filenames
|
||||
* @param boolean include the index_page in the link
|
||||
* @return string
|
||||
*/
|
||||
public static function stylesheet($style, $media = FALSE, $index = FALSE)
|
||||
{
|
||||
return html::link($style, 'stylesheet', 'text/css', $media, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link tag.
|
||||
*
|
||||
* @param string|array filename
|
||||
* @param string|array relationship
|
||||
* @param string|array mimetype
|
||||
* @param string|array specifies on what device the document will be displayed
|
||||
* @param boolean include the index_page in the link
|
||||
* @return string
|
||||
*/
|
||||
public static function link($href, $rel, $type, $media = FALSE, $index = FALSE)
|
||||
{
|
||||
$compiled = '';
|
||||
|
||||
if (is_array($href))
|
||||
{
|
||||
foreach ($href as $_href)
|
||||
{
|
||||
$_rel = is_array($rel) ? array_shift($rel) : $rel;
|
||||
$_type = is_array($type) ? array_shift($type) : $type;
|
||||
$_media = is_array($media) ? array_shift($media) : $media;
|
||||
|
||||
$compiled .= html::link($_href, $_rel, $_type, $_media, $index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strpos($href, '://') === FALSE)
|
||||
{
|
||||
// Make the URL absolute
|
||||
$href = url::base($index).$href;
|
||||
}
|
||||
|
||||
$attr = array
|
||||
(
|
||||
'rel' => $rel,
|
||||
'type' => $type,
|
||||
'href' => $href,
|
||||
);
|
||||
|
||||
if ( ! empty($media))
|
||||
{
|
||||
// Add the media type to the attributes
|
||||
$attr['media'] = $media;
|
||||
}
|
||||
|
||||
$compiled = '<link'.html::attributes($attr).' />';
|
||||
}
|
||||
|
||||
return $compiled."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a script link.
|
||||
*
|
||||
* @param string|array filename
|
||||
* @param boolean include the index_page in the link
|
||||
* @return string
|
||||
*/
|
||||
public static function script($script, $index = FALSE)
|
||||
{
|
||||
$compiled = '';
|
||||
|
||||
if (is_array($script))
|
||||
{
|
||||
foreach ($script as $name)
|
||||
{
|
||||
$compiled .= html::script($name, $index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strpos($script, '://') === FALSE)
|
||||
{
|
||||
// Add the suffix only when it's not already present
|
||||
$script = url::base((bool) $index).$script;
|
||||
}
|
||||
|
||||
$compiled = '<script type="text/javascript" src="'.$script.'"></script>';
|
||||
}
|
||||
|
||||
return $compiled."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a image link.
|
||||
*
|
||||
* @param string image source, or an array of attributes
|
||||
* @param string|array image alt attribute, or an array of attributes
|
||||
* @param boolean include the index_page in the link
|
||||
* @return string
|
||||
*/
|
||||
public static function image($src = NULL, $alt = NULL, $index = FALSE)
|
||||
{
|
||||
// Create attribute list
|
||||
$attributes = is_array($src) ? $src : array('src' => $src);
|
||||
|
||||
if (is_array($alt))
|
||||
{
|
||||
$attributes += $alt;
|
||||
}
|
||||
elseif ( ! empty($alt))
|
||||
{
|
||||
// Add alt to attributes
|
||||
$attributes['alt'] = $alt;
|
||||
}
|
||||
|
||||
if (strpos($attributes['src'], '://') === FALSE)
|
||||
{
|
||||
// Make the src attribute into an absolute URL
|
||||
$attributes['src'] = url::base($index).$attributes['src'];
|
||||
}
|
||||
|
||||
return '<img'.html::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an array of HTML attributes into an attribute string.
|
||||
*
|
||||
* @param string|array array of attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes($attrs)
|
||||
{
|
||||
if (empty($attrs))
|
||||
return '';
|
||||
|
||||
if (is_string($attrs))
|
||||
return ' '.$attrs;
|
||||
|
||||
$compiled = '';
|
||||
foreach ($attrs as $key => $val)
|
||||
{
|
||||
$compiled .= ' '.$key.'="'.htmlspecialchars($val, ENT_QUOTES, Kohana::CHARSET).'"';
|
||||
}
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
} // End html
|
254
web_client/system/helpers/inflector.php
Normal file
@ -0,0 +1,254 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Inflector helper class.
|
||||
*
|
||||
* $Id: inflector.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class inflector_Core {
|
||||
|
||||
// Cached inflections
|
||||
protected static $cache = array();
|
||||
|
||||
// Uncountable and irregular words
|
||||
protected static $uncountable;
|
||||
protected static $irregular;
|
||||
|
||||
/**
|
||||
* Checks if a word is defined as uncountable.
|
||||
*
|
||||
* @param string word to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function uncountable($str)
|
||||
{
|
||||
if (inflector::$uncountable === NULL)
|
||||
{
|
||||
// Cache uncountables
|
||||
inflector::$uncountable = Kohana::config('inflector.uncountable');
|
||||
|
||||
// Make uncountables mirroed
|
||||
inflector::$uncountable = array_combine(inflector::$uncountable, inflector::$uncountable);
|
||||
}
|
||||
|
||||
return isset(inflector::$uncountable[strtolower($str)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a plural word singular.
|
||||
*
|
||||
* @param string word to singularize
|
||||
* @param integer number of things
|
||||
* @return string
|
||||
*/
|
||||
public static function singular($str, $count = NULL) {
|
||||
$parts = explode('_', $str);
|
||||
|
||||
$last = inflector::_singular(array_pop($parts), $count);
|
||||
|
||||
$pre = implode('_', $parts);
|
||||
if (strlen($pre))
|
||||
$pre .= '_';
|
||||
|
||||
return $pre.$last;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes a plural word singular.
|
||||
*
|
||||
* @param string word to singularize
|
||||
* @param integer number of things
|
||||
* @return string
|
||||
*/
|
||||
public static function _singular($str, $count = NULL)
|
||||
{
|
||||
// Remove garbage
|
||||
$str = strtolower(trim($str));
|
||||
|
||||
if (is_string($count))
|
||||
{
|
||||
// Convert to integer when using a digit string
|
||||
$count = (int) $count;
|
||||
}
|
||||
|
||||
// Do nothing with a single count
|
||||
if ($count === 0 OR $count > 1)
|
||||
return $str;
|
||||
|
||||
// Cache key name
|
||||
$key = 'singular_'.$str.$count;
|
||||
|
||||
if (isset(inflector::$cache[$key]))
|
||||
return inflector::$cache[$key];
|
||||
|
||||
if (inflector::uncountable($str))
|
||||
return inflector::$cache[$key] = $str;
|
||||
|
||||
if (empty(inflector::$irregular))
|
||||
{
|
||||
// Cache irregular words
|
||||
inflector::$irregular = Kohana::config('inflector.irregular');
|
||||
}
|
||||
|
||||
if ($irregular = array_search($str, inflector::$irregular))
|
||||
{
|
||||
$str = $irregular;
|
||||
}
|
||||
elseif (preg_match('/[sxz]es$/', $str) OR preg_match('/[^aeioudgkprt]hes$/', $str))
|
||||
{
|
||||
// Remove "es"
|
||||
$str = substr($str, 0, -2);
|
||||
}
|
||||
elseif (preg_match('/[^aeiou]ies$/', $str))
|
||||
{
|
||||
$str = substr($str, 0, -3).'y';
|
||||
}
|
||||
elseif (substr($str, -1) === 's' AND substr($str, -2) !== 'ss')
|
||||
{
|
||||
$str = substr($str, 0, -1);
|
||||
}
|
||||
|
||||
return inflector::$cache[$key] = $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a singular word plural.
|
||||
*
|
||||
* @param string word to pluralize
|
||||
* @return string
|
||||
*/
|
||||
public static function plural($str, $count = NULL)
|
||||
{
|
||||
if ( ! $str)
|
||||
return $str;
|
||||
|
||||
$parts = explode('_', $str);
|
||||
|
||||
$last = inflector::_plural(array_pop($parts), $count);
|
||||
|
||||
$pre = implode('_', $parts);
|
||||
if (strlen($pre))
|
||||
$pre .= '_';
|
||||
|
||||
return $pre.$last;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes a singular word plural.
|
||||
*
|
||||
* @param string word to pluralize
|
||||
* @return string
|
||||
*/
|
||||
public static function _plural($str, $count = NULL)
|
||||
{
|
||||
// Remove garbage
|
||||
$str = strtolower(trim($str));
|
||||
|
||||
if (is_string($count))
|
||||
{
|
||||
// Convert to integer when using a digit string
|
||||
$count = (int) $count;
|
||||
}
|
||||
|
||||
// Do nothing with singular
|
||||
if ($count === 1)
|
||||
return $str;
|
||||
|
||||
// Cache key name
|
||||
$key = 'plural_'.$str.$count;
|
||||
|
||||
if (isset(inflector::$cache[$key]))
|
||||
return inflector::$cache[$key];
|
||||
|
||||
if (inflector::uncountable($str))
|
||||
return inflector::$cache[$key] = $str;
|
||||
|
||||
if (empty(inflector::$irregular))
|
||||
{
|
||||
// Cache irregular words
|
||||
inflector::$irregular = Kohana::config('inflector.irregular');
|
||||
}
|
||||
|
||||
if (isset(inflector::$irregular[$str]))
|
||||
{
|
||||
$str = inflector::$irregular[$str];
|
||||
}
|
||||
elseif (preg_match('/[sxz]$/', $str) OR preg_match('/[^aeioudgkprt]h$/', $str))
|
||||
{
|
||||
$str .= 'es';
|
||||
}
|
||||
elseif (preg_match('/[^aeiou]y$/', $str))
|
||||
{
|
||||
// Change "y" to "ies"
|
||||
$str = substr_replace($str, 'ies', -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$str .= 's';
|
||||
}
|
||||
|
||||
// Set the cache and return
|
||||
return inflector::$cache[$key] = $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a word possessive.
|
||||
*
|
||||
* @param string word to to make possessive
|
||||
* @return string
|
||||
*/
|
||||
public static function possessive($string)
|
||||
{
|
||||
$length = strlen($string);
|
||||
|
||||
if (substr($string, $length - 1, $length) == 's')
|
||||
{
|
||||
return $string.'\'';
|
||||
}
|
||||
|
||||
return $string.'\'s';
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a phrase camel case.
|
||||
*
|
||||
* @param string phrase to camelize
|
||||
* @return string
|
||||
*/
|
||||
public static function camelize($str)
|
||||
{
|
||||
$str = 'x'.strtolower(trim($str));
|
||||
$str = ucwords(preg_replace('/[\s_]+/', ' ', $str));
|
||||
|
||||
return substr(str_replace(' ', '', $str), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a phrase underscored instead of spaced.
|
||||
*
|
||||
* @param string phrase to underscore
|
||||
* @return string
|
||||
*/
|
||||
public static function underscore($str)
|
||||
{
|
||||
return trim(preg_replace('/[\s_]+/', '_', $str), '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an underscored or dashed phrase human-reable.
|
||||
*
|
||||
* @param string phrase to make human-reable
|
||||
* @return string
|
||||
*/
|
||||
public static function humanize($str)
|
||||
{
|
||||
return trim(preg_replace('/[_-\s]+/', ' ', $str));
|
||||
}
|
||||
|
||||
} // End inflector
|
26
web_client/system/helpers/num.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Number helper class.
|
||||
*
|
||||
* $Id: num.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class num_Core {
|
||||
|
||||
/**
|
||||
* Round a number to the nearest nth
|
||||
*
|
||||
* @param integer number to round
|
||||
* @param integer number to round to
|
||||
* @return integer
|
||||
*/
|
||||
public static function round($number, $nearest = 5)
|
||||
{
|
||||
return round($number / $nearest) * $nearest;
|
||||
}
|
||||
|
||||
} // End num
|
66
web_client/system/helpers/remote.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Remote url/file helper.
|
||||
*
|
||||
* $Id: remote.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class remote_Core {
|
||||
|
||||
public static function status($url)
|
||||
{
|
||||
if ( ! valid::url($url, 'http'))
|
||||
return FALSE;
|
||||
|
||||
// Get the hostname and path
|
||||
$url = parse_url($url);
|
||||
|
||||
if (empty($url['path']))
|
||||
{
|
||||
// Request the root document
|
||||
$url['path'] = '/';
|
||||
}
|
||||
|
||||
// Open a remote connection
|
||||
$remote = fsockopen($url['host'], 80, $errno, $errstr, 5);
|
||||
|
||||
if ( ! is_resource($remote))
|
||||
return FALSE;
|
||||
|
||||
// Set CRLF
|
||||
$CRLF = "\r\n";
|
||||
|
||||
// Send request
|
||||
fwrite($remote, 'HEAD '.$url['path'].(isset($url['query']) ? '?'.$url['query'] : '').' HTTP/1.0'.$CRLF);
|
||||
fwrite($remote, 'Host: '.$url['host'].$CRLF);
|
||||
fwrite($remote, 'Connection: close'.$CRLF);
|
||||
fwrite($remote, 'User-Agent: Kohana Framework (+http://kohanaphp.com/)'.$CRLF);
|
||||
|
||||
// Send one more CRLF to terminate the headers
|
||||
fwrite($remote, $CRLF);
|
||||
|
||||
while ( ! feof($remote))
|
||||
{
|
||||
// Get the line
|
||||
$line = trim(fgets($remote, 512));
|
||||
|
||||
if ($line !== '' AND preg_match('#^HTTP/1\.[01] (\d{3})#', $line, $matches))
|
||||
{
|
||||
// Response code found
|
||||
$response = (int) $matches[1];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
fclose($remote);
|
||||
|
||||
return isset($response) ? $response : FALSE;
|
||||
}
|
||||
|
||||
} // End remote
|
619
web_client/system/helpers/request.php
Normal file
@ -0,0 +1,619 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Request helper class.
|
||||
*
|
||||
* $Id: request.php 4692 2009-12-04 15:59:44Z cbandy $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class request_Core {
|
||||
|
||||
// Possible HTTP methods
|
||||
protected static $http_methods = array('get', 'head', 'options', 'post', 'put', 'delete');
|
||||
|
||||
// Character sets from client's HTTP Accept-Charset request header
|
||||
protected static $accept_charsets;
|
||||
|
||||
// Content codings from client's HTTP Accept-Encoding request header
|
||||
protected static $accept_encodings;
|
||||
|
||||
// Language tags from client's HTTP Accept-Language request header
|
||||
protected static $accept_languages;
|
||||
|
||||
// Content types from client's HTTP Accept request header
|
||||
protected static $accept_types;
|
||||
|
||||
// The current user agent and its parsed attributes
|
||||
protected static $user_agent;
|
||||
|
||||
/**
|
||||
* Returns the HTTP referrer, or the default if the referrer is not set.
|
||||
*
|
||||
* @param mixed default to return
|
||||
* @param bool Remove base URL
|
||||
* @return string
|
||||
*/
|
||||
public static function referrer($default = FALSE, $remove_base = FALSE)
|
||||
{
|
||||
if ( ! empty($_SERVER['HTTP_REFERER']))
|
||||
{
|
||||
// Set referrer
|
||||
$ref = $_SERVER['HTTP_REFERER'];
|
||||
|
||||
if ($remove_base === TRUE AND (strpos($ref, url::base(FALSE)) === 0))
|
||||
{
|
||||
// Remove the base URL from the referrer
|
||||
$ref = substr($ref, strlen(url::base(FALSE)));
|
||||
}
|
||||
}
|
||||
|
||||
return isset($ref) ? $ref : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current request protocol, based on $_SERVER['https']. In CLI
|
||||
* mode, NULL will be returned.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function protocol()
|
||||
{
|
||||
if (Kohana::$server_api === 'cli')
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
elseif ( ! empty($_SERVER['HTTPS']) AND $_SERVER['HTTPS'] === 'on')
|
||||
{
|
||||
return 'https';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'http';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the current request is an AJAX request by checking the X-Requested-With HTTP
|
||||
* request header that most popular JS frameworks now set for AJAX calls.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_ajax()
|
||||
{
|
||||
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current request method.
|
||||
*
|
||||
* @throws Kohana_Exception in case of an unknown request method
|
||||
* @return string
|
||||
*/
|
||||
public static function method()
|
||||
{
|
||||
$method = strtolower($_SERVER['REQUEST_METHOD']);
|
||||
|
||||
if ( ! in_array($method, request::$http_methods))
|
||||
throw new Kohana_Exception('Invalid request method :method:', array(':method:' => $method));
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves current user agent information
|
||||
* keys: browser, version, platform, mobile, robot
|
||||
*
|
||||
* @param string key
|
||||
* @return mixed NULL or the parsed value
|
||||
*/
|
||||
public static function user_agent($key = 'agent')
|
||||
{
|
||||
// Retrieve raw user agent without parsing
|
||||
if ($key === 'agent')
|
||||
{
|
||||
if (request::$user_agent === NULL)
|
||||
return request::$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : '';
|
||||
|
||||
if (is_array(request::$user_agent))
|
||||
return request::$user_agent['agent'];
|
||||
|
||||
return request::$user_agent;
|
||||
}
|
||||
|
||||
if ( ! is_array(request::$user_agent))
|
||||
{
|
||||
request::$user_agent['agent'] = isset($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : '';
|
||||
|
||||
// Parse the user agent and extract basic information
|
||||
foreach (Kohana::config('user_agents') as $type => $data)
|
||||
{
|
||||
foreach ($data as $fragment => $name)
|
||||
{
|
||||
if (stripos(request::$user_agent['agent'], $fragment) !== FALSE)
|
||||
{
|
||||
if ($type === 'browser' AND preg_match('|'.preg_quote($fragment).'[^0-9.]*+([0-9.][0-9.a-z]*)|i', request::$user_agent['agent'], $match))
|
||||
{
|
||||
// Set the browser version
|
||||
request::$user_agent['version'] = $match[1];
|
||||
}
|
||||
|
||||
// Set the agent name
|
||||
request::$user_agent[$type] = $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isset(request::$user_agent[$key]) ? request::$user_agent[$key] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns boolean of whether client accepts content type.
|
||||
*
|
||||
* @param string content type
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return boolean
|
||||
*/
|
||||
public static function accepts($type = NULL, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_content_header();
|
||||
|
||||
if ($type === NULL)
|
||||
return request::$accept_types;
|
||||
|
||||
return (request::accepts_at_quality($type, $explicit_check) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns boolean indicating if the client accepts a charset
|
||||
*
|
||||
* @param string
|
||||
* @return boolean
|
||||
*/
|
||||
public static function accepts_charset($charset = NULL)
|
||||
{
|
||||
request::parse_accept_charset_header();
|
||||
|
||||
if ($charset === NULL)
|
||||
return request::$accept_charsets;
|
||||
|
||||
return (request::accepts_charset_at_quality($charset) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns boolean indicating if the client accepts an encoding
|
||||
*
|
||||
* @param string
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return boolean
|
||||
*/
|
||||
public static function accepts_encoding($encoding = NULL, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_encoding_header();
|
||||
|
||||
if ($encoding === NULL)
|
||||
return request::$accept_encodings;
|
||||
|
||||
return (request::accepts_encoding_at_quality($encoding, $explicit_check) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns boolean indicating if the client accepts a language tag
|
||||
*
|
||||
* @param string language tag
|
||||
* @param boolean set to TRUE to disable prefix and wildcard checking
|
||||
* @return boolean
|
||||
*/
|
||||
public static function accepts_language($tag = NULL, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_language_header();
|
||||
|
||||
if ($tag === NULL)
|
||||
return request::$accept_languages;
|
||||
|
||||
return (request::accepts_language_at_quality($tag, $explicit_check) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the q values for given array of content types and return the one with the highest value.
|
||||
* If items are found to have the same q value, the first one encountered in the given array wins.
|
||||
* If all items in the given array have a q value of 0, FALSE is returned.
|
||||
*
|
||||
* @param array content types
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return mixed string mime type with highest q value, FALSE if none of the given types are accepted
|
||||
*/
|
||||
public static function preferred_accept($types, $explicit_check = FALSE)
|
||||
{
|
||||
$max_q = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($types as $type)
|
||||
{
|
||||
$q = request::accepts_at_quality($type, $explicit_check);
|
||||
|
||||
if ($q > $max_q)
|
||||
{
|
||||
$max_q = $q;
|
||||
$preferred = $type;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the q values for a given array of character sets and return the
|
||||
* one with the highest value. If items are found to have the same q value,
|
||||
* the first one encountered takes precedence. If all items in the given
|
||||
* array have a q value of 0, FALSE is returned.
|
||||
*
|
||||
* @param array character sets
|
||||
* @return mixed
|
||||
*/
|
||||
public static function preferred_charset($charsets)
|
||||
{
|
||||
$max_q = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($charsets as $charset)
|
||||
{
|
||||
$q = request::accepts_charset_at_quality($charset);
|
||||
|
||||
if ($q > $max_q)
|
||||
{
|
||||
$max_q = $q;
|
||||
$preferred = $charset;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the q values for a given array of encodings and return the one with
|
||||
* the highest value. If items are found to have the same q value, the first
|
||||
* one encountered takes precedence. If all items in the given array have
|
||||
* a q value of 0, FALSE is returned.
|
||||
*
|
||||
* @param array encodings
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return mixed
|
||||
*/
|
||||
public static function preferred_encoding($encodings, $explicit_check = FALSE)
|
||||
{
|
||||
$max_q = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($encodings as $encoding)
|
||||
{
|
||||
$q = request::accepts_encoding_at_quality($encoding, $explicit_check);
|
||||
|
||||
if ($q > $max_q)
|
||||
{
|
||||
$max_q = $q;
|
||||
$preferred = $encoding;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the q values for a given array of language tags and return the
|
||||
* one with the highest value. If items are found to have the same q value,
|
||||
* the first one encountered takes precedence. If all items in the given
|
||||
* array have a q value of 0, FALSE is returned.
|
||||
*
|
||||
* @param array language tags
|
||||
* @param boolean set to TRUE to disable prefix and wildcard checking
|
||||
* @return mixed
|
||||
*/
|
||||
public static function preferred_language($tags, $explicit_check = FALSE)
|
||||
{
|
||||
$max_q = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($tags as $tag)
|
||||
{
|
||||
$q = request::accepts_language_at_quality($tag, $explicit_check);
|
||||
|
||||
if ($q > $max_q)
|
||||
{
|
||||
$max_q = $q;
|
||||
$preferred = $tag;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns quality factor at which the client accepts content type
|
||||
*
|
||||
* @param string content type (e.g. "image/jpg", "jpg")
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return integer|float
|
||||
*/
|
||||
public static function accepts_at_quality($type, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_content_header();
|
||||
|
||||
// Normalize type
|
||||
$type = strtolower($type);
|
||||
|
||||
// General content type (e.g. "jpg")
|
||||
if (strpos($type, '/') === FALSE)
|
||||
{
|
||||
// Don't accept anything by default
|
||||
$q = 0;
|
||||
|
||||
// Look up relevant mime types
|
||||
foreach ((array) Kohana::config('mimes.'.$type) as $type)
|
||||
{
|
||||
$q2 = request::accepts_at_quality($type, $explicit_check);
|
||||
$q = ($q2 > $q) ? $q2 : $q;
|
||||
}
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
// Content type with subtype given (e.g. "image/jpg")
|
||||
$type = explode('/', $type, 2);
|
||||
|
||||
// Exact match
|
||||
if (isset(request::$accept_types[$type[0]][$type[1]]))
|
||||
return request::$accept_types[$type[0]][$type[1]];
|
||||
|
||||
if ($explicit_check === FALSE)
|
||||
{
|
||||
// Wildcard match
|
||||
if (isset(request::$accept_types[$type[0]]['*']))
|
||||
return request::$accept_types[$type[0]]['*'];
|
||||
|
||||
// Catch-all wildcard match
|
||||
if (isset(request::$accept_types['*']['*']))
|
||||
return request::$accept_types['*']['*'];
|
||||
}
|
||||
|
||||
// Content type not accepted
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns quality factor at which the client accepts a charset
|
||||
*
|
||||
* @param string charset (e.g., "ISO-8859-1", "utf-8")
|
||||
* @return integer|float
|
||||
*/
|
||||
public static function accepts_charset_at_quality($charset)
|
||||
{
|
||||
request::parse_accept_charset_header();
|
||||
|
||||
// Normalize charset
|
||||
$charset = strtolower($charset);
|
||||
|
||||
// Exact match
|
||||
if (isset(request::$accept_charsets[$charset]))
|
||||
return request::$accept_charsets[$charset];
|
||||
|
||||
if (isset(request::$accept_charsets['*']))
|
||||
return request::$accept_charsets['*'];
|
||||
|
||||
if ($charset === 'iso-8859-1')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns quality factor at which the client accepts an encoding
|
||||
*
|
||||
* @param string encoding (e.g., "gzip", "deflate")
|
||||
* @param boolean set to TRUE to disable wildcard checking
|
||||
* @return integer|float
|
||||
*/
|
||||
public static function accepts_encoding_at_quality($encoding, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_encoding_header();
|
||||
|
||||
// Normalize encoding
|
||||
$encoding = strtolower($encoding);
|
||||
|
||||
// Exact match
|
||||
if (isset(request::$accept_encodings[$encoding]))
|
||||
return request::$accept_encodings[$encoding];
|
||||
|
||||
if ($explicit_check === FALSE)
|
||||
{
|
||||
if (isset(request::$accept_encodings['*']))
|
||||
return request::$accept_encodings['*'];
|
||||
|
||||
if ($encoding === 'identity')
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns quality factor at which the client accepts a language
|
||||
*
|
||||
* @param string tag (e.g., "en", "en-us", "fr-ca")
|
||||
* @param boolean set to TRUE to disable prefix and wildcard checking
|
||||
* @return integer|float
|
||||
*/
|
||||
public static function accepts_language_at_quality($tag, $explicit_check = FALSE)
|
||||
{
|
||||
request::parse_accept_language_header();
|
||||
|
||||
$tag = explode('-', strtolower($tag), 2);
|
||||
|
||||
if (isset(request::$accept_languages[$tag[0]]))
|
||||
{
|
||||
if (isset($tag[1]))
|
||||
{
|
||||
// Exact match
|
||||
if (isset(request::$accept_languages[$tag[0]][$tag[1]]))
|
||||
return request::$accept_languages[$tag[0]][$tag[1]];
|
||||
|
||||
// A prefix matches
|
||||
if ($explicit_check === FALSE AND isset(request::$accept_languages[$tag[0]]['*']))
|
||||
return request::$accept_languages[$tag[0]]['*'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// No subtags
|
||||
if (isset(request::$accept_languages[$tag[0]]['*']))
|
||||
return request::$accept_languages[$tag[0]]['*'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($explicit_check === FALSE AND isset(request::$accept_languages['*']))
|
||||
return request::$accept_languages['*'];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a HTTP Accept or Accept-* header for q values
|
||||
*
|
||||
* @param string header data
|
||||
* @return array
|
||||
*/
|
||||
protected static function parse_accept_header($header)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
// Remove linebreaks and parse the HTTP Accept header
|
||||
foreach (explode(',', str_replace(array("\r", "\n"), '', strtolower($header))) as $entry)
|
||||
{
|
||||
// Explode each entry in content type and possible quality factor
|
||||
$entry = explode(';', trim($entry), 2);
|
||||
|
||||
$q = (isset($entry[1]) AND preg_match('~\bq\s*+=\s*+([.0-9]+)~', $entry[1], $match)) ? (float) $match[1] : 1;
|
||||
|
||||
// Overwrite entries with a smaller q value
|
||||
if ( ! isset($result[$entry[0]]) OR $q > $result[$entry[0]])
|
||||
{
|
||||
$result[$entry[0]] = $q;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a client's HTTP Accept-Charset header
|
||||
*/
|
||||
protected static function parse_accept_charset_header()
|
||||
{
|
||||
// Run this function just once
|
||||
if (request::$accept_charsets !== NULL)
|
||||
return;
|
||||
|
||||
// No HTTP Accept-Charset header found
|
||||
if (empty($_SERVER['HTTP_ACCEPT_CHARSET']))
|
||||
{
|
||||
// Accept everything
|
||||
request::$accept_charsets['*'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
request::$accept_charsets = request::parse_accept_header($_SERVER['HTTP_ACCEPT_CHARSET']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a client's HTTP Accept header
|
||||
*/
|
||||
protected static function parse_accept_content_header()
|
||||
{
|
||||
// Run this function just once
|
||||
if (request::$accept_types !== NULL)
|
||||
return;
|
||||
|
||||
// No HTTP Accept header found
|
||||
if (empty($_SERVER['HTTP_ACCEPT']))
|
||||
{
|
||||
// Accept everything
|
||||
request::$accept_types['*']['*'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
request::$accept_types = array();
|
||||
|
||||
foreach (request::parse_accept_header($_SERVER['HTTP_ACCEPT']) as $type => $q)
|
||||
{
|
||||
// Explode each content type (e.g. "text/html")
|
||||
$type = explode('/', $type, 2);
|
||||
|
||||
// Skip invalid content types
|
||||
if ( ! isset($type[1]))
|
||||
continue;
|
||||
|
||||
request::$accept_types[$type[0]][$type[1]] = $q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a client's HTTP Accept-Encoding header
|
||||
*/
|
||||
protected static function parse_accept_encoding_header()
|
||||
{
|
||||
// Run this function just once
|
||||
if (request::$accept_encodings !== NULL)
|
||||
return;
|
||||
|
||||
// No HTTP Accept-Encoding header found
|
||||
if ( ! isset($_SERVER['HTTP_ACCEPT_ENCODING']))
|
||||
{
|
||||
// Accept everything
|
||||
request::$accept_encodings['*'] = 1;
|
||||
}
|
||||
elseif ($_SERVER['HTTP_ACCEPT_ENCODING'] === '')
|
||||
{
|
||||
// Accept only identity
|
||||
request::$accept_encodings['identity'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
request::$accept_encodings = request::parse_accept_header($_SERVER['HTTP_ACCEPT_ENCODING']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a client's HTTP Accept-Language header
|
||||
*/
|
||||
protected static function parse_accept_language_header()
|
||||
{
|
||||
// Run this function just once
|
||||
if (request::$accept_languages !== NULL)
|
||||
return;
|
||||
|
||||
// No HTTP Accept-Language header found
|
||||
if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
{
|
||||
// Accept everything
|
||||
request::$accept_languages['*'] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
request::$accept_languages = array();
|
||||
|
||||
foreach (request::parse_accept_header($_SERVER['HTTP_ACCEPT_LANGUAGE']) as $tag => $q)
|
||||
{
|
||||
// Explode each language (e.g. "en-us")
|
||||
$tag = explode('-', $tag, 2);
|
||||
|
||||
request::$accept_languages[$tag[0]][isset($tag[1]) ? $tag[1] : '*'] = $q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End request
|
37
web_client/system/helpers/security.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Security helper class.
|
||||
*
|
||||
* $Id: security.php 4698 2009-12-08 18:39:33Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class security_Core {
|
||||
|
||||
/**
|
||||
* Sanitize a string with the xss_clean method.
|
||||
*
|
||||
* @param string string to sanitize
|
||||
* @param string xss_clean method to use ('htmlpurifier' or defaults to built-in method)
|
||||
* @return string
|
||||
*/
|
||||
public static function xss_clean($str, $tool = NULL)
|
||||
{
|
||||
return Input::instance()->xss_clean($str, $tool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove image tags from a string.
|
||||
*
|
||||
* @param string string to sanitize
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_image_tags($str)
|
||||
{
|
||||
return preg_replace('#<img\s.*?(?:src\s*=\s*["\']?([^"\'<>\s]*)["\']?[^>]*)?>#is', '$1', $str);
|
||||
}
|
||||
|
||||
} // End security
|
598
web_client/system/helpers/text.php
Normal file
@ -0,0 +1,598 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Text helper class.
|
||||
*
|
||||
* $Id: text.php 4689 2009-12-02 01:39:24Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class text_Core {
|
||||
|
||||
/**
|
||||
* Limits a phrase to a given number of words.
|
||||
*
|
||||
* @param string phrase to limit words of
|
||||
* @param integer number of words to limit to
|
||||
* @param string end character or entity
|
||||
* @return string
|
||||
*/
|
||||
public static function limit_words($str, $limit = 100, $end_char = NULL)
|
||||
{
|
||||
$limit = (int) $limit;
|
||||
$end_char = ($end_char === NULL) ? '…' : $end_char;
|
||||
|
||||
if (trim($str) === '')
|
||||
return $str;
|
||||
|
||||
if ($limit <= 0)
|
||||
return $end_char;
|
||||
|
||||
preg_match('/^\s*+(?:\S++\s*+){1,'.$limit.'}/u', $str, $matches);
|
||||
|
||||
// Only attach the end character if the matched string is shorter
|
||||
// than the starting string.
|
||||
return rtrim($matches[0]).(strlen($matches[0]) === strlen($str) ? '' : $end_char);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits a phrase to a given number of characters.
|
||||
*
|
||||
* @param string phrase to limit characters of
|
||||
* @param integer number of characters to limit to
|
||||
* @param string end character or entity
|
||||
* @param boolean enable or disable the preservation of words while limiting
|
||||
* @return string
|
||||
*/
|
||||
public static function limit_chars($str, $limit = 100, $end_char = NULL, $preserve_words = FALSE)
|
||||
{
|
||||
$end_char = ($end_char === NULL) ? '…' : $end_char;
|
||||
|
||||
$limit = (int) $limit;
|
||||
|
||||
if (trim($str) === '' OR mb_strlen($str) <= $limit)
|
||||
return $str;
|
||||
|
||||
if ($limit <= 0)
|
||||
return $end_char;
|
||||
|
||||
if ($preserve_words == FALSE)
|
||||
{
|
||||
return rtrim(mb_substr($str, 0, $limit)).$end_char;
|
||||
}
|
||||
|
||||
preg_match('/^.{'.($limit - 1).'}\S*/us', $str, $matches);
|
||||
|
||||
return rtrim($matches[0]).(strlen($matches[0]) == strlen($str) ? '' : $end_char);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternates between two or more strings.
|
||||
*
|
||||
* @param string strings to alternate between
|
||||
* @return string
|
||||
*/
|
||||
public static function alternate()
|
||||
{
|
||||
static $i;
|
||||
|
||||
if (func_num_args() === 0)
|
||||
{
|
||||
$i = 0;
|
||||
return '';
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
return $args[($i++ % count($args))];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random string of a given type and length.
|
||||
*
|
||||
* @param string a type of pool, or a string of characters to use as the pool
|
||||
* @param integer length of string to return
|
||||
* @return string
|
||||
*
|
||||
* @tutorial alnum alpha-numeric characters
|
||||
* @tutorial alpha alphabetical characters
|
||||
* @tutorial hexdec hexadecimal characters, 0-9 plus a-f
|
||||
* @tutorial numeric digit characters, 0-9
|
||||
* @tutorial nozero digit characters, 1-9
|
||||
* @tutorial distinct clearly distinct alpha-numeric characters
|
||||
*/
|
||||
public static function random($type = 'alnum', $length = 8)
|
||||
{
|
||||
$utf8 = FALSE;
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'alnum':
|
||||
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
case 'alpha':
|
||||
$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
break;
|
||||
case 'hexdec':
|
||||
$pool = '0123456789abcdef';
|
||||
break;
|
||||
case 'numeric':
|
||||
$pool = '0123456789';
|
||||
break;
|
||||
case 'nozero':
|
||||
$pool = '123456789';
|
||||
break;
|
||||
case 'distinct':
|
||||
$pool = '2345679ACDEFHJKLMNPRSTUVWXYZ';
|
||||
break;
|
||||
default:
|
||||
$pool = (string) $type;
|
||||
$utf8 = ! text::is_ascii($pool);
|
||||
break;
|
||||
}
|
||||
|
||||
// Split the pool into an array of characters
|
||||
$pool = ($utf8 === TRUE) ? utf8::str_split($pool, 1) : str_split($pool, 1);
|
||||
|
||||
// Largest pool key
|
||||
$max = count($pool) - 1;
|
||||
|
||||
$str = '';
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
// Select a random character from the pool and add it to the string
|
||||
$str .= $pool[mt_rand(0, $max)];
|
||||
}
|
||||
|
||||
// Make sure alnum strings contain at least one letter and one digit
|
||||
if ($type === 'alnum' AND $length > 1)
|
||||
{
|
||||
if (ctype_alpha($str))
|
||||
{
|
||||
// Add a random digit
|
||||
$str[mt_rand(0, $length - 1)] = chr(mt_rand(48, 57));
|
||||
}
|
||||
elseif (ctype_digit($str))
|
||||
{
|
||||
// Add a random letter
|
||||
$str[mt_rand(0, $length - 1)] = chr(mt_rand(65, 90));
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces multiple slashes in a string to single slashes.
|
||||
*
|
||||
* @param string string to reduce slashes of
|
||||
* @return string
|
||||
*/
|
||||
public static function reduce_slashes($str)
|
||||
{
|
||||
return preg_replace('#(?<!:)//+#', '/', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the given words with a string.
|
||||
*
|
||||
* @param string phrase to replace words in
|
||||
* @param array words to replace
|
||||
* @param string replacement string
|
||||
* @param boolean replace words across word boundries (space, period, etc)
|
||||
* @return string
|
||||
*/
|
||||
public static function censor($str, $badwords, $replacement = '#', $replace_partial_words = TRUE)
|
||||
{
|
||||
foreach ((array) $badwords as $key => $badword)
|
||||
{
|
||||
$badwords[$key] = str_replace('\*', '\S*?', preg_quote((string) $badword));
|
||||
}
|
||||
|
||||
$regex = '('.implode('|', $badwords).')';
|
||||
|
||||
if ($replace_partial_words === FALSE)
|
||||
{
|
||||
// Just using \b isn't sufficient when we need to replace a badword that already contains word boundaries itself
|
||||
$regex = '(?<=\b|\s|^)'.$regex.'(?=\b|\s|$)';
|
||||
}
|
||||
|
||||
$regex = '!'.$regex.'!ui';
|
||||
|
||||
if (mb_strlen($replacement) == 1)
|
||||
{
|
||||
$regex .= 'e';
|
||||
return preg_replace($regex, 'str_repeat($replacement, mb_strlen(\'$1\'))', $str);
|
||||
}
|
||||
|
||||
return preg_replace($regex, $replacement, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the text that is similar between a set of words.
|
||||
*
|
||||
* @param array words to find similar text of
|
||||
* @return string
|
||||
*/
|
||||
public static function similar(array $words)
|
||||
{
|
||||
// First word is the word to match against
|
||||
$word = current($words);
|
||||
|
||||
for ($i = 0, $max = strlen($word); $i < $max; ++$i)
|
||||
{
|
||||
foreach ($words as $w)
|
||||
{
|
||||
// Once a difference is found, break out of the loops
|
||||
if ( ! isset($w[$i]) OR $w[$i] !== $word[$i])
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the similar text
|
||||
return substr($word, 0, $i);
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative to the php levenshtein() function that work out the
|
||||
* distance between 2 words using the Damerau–Levenshtein algorithm.
|
||||
* Credit: http://forums.devnetwork.net/viewtopic.php?f=50&t=89094
|
||||
*
|
||||
* @see http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
|
||||
* @param string first word
|
||||
* @param string second word
|
||||
* @return int distance between words
|
||||
*/
|
||||
public static function distance($string1, $string2)
|
||||
{
|
||||
$string1_length = strlen($string1);
|
||||
$string2_length = strlen($string2);
|
||||
|
||||
// Here we start building the table of values
|
||||
$matrix = array();
|
||||
|
||||
// String1 length + 1 = rows.
|
||||
for ($i = 0; $i <= $string1_length; ++$i)
|
||||
{
|
||||
$matrix[$i][0] = $i;
|
||||
}
|
||||
|
||||
// String2 length + 1 columns.
|
||||
for ($j = 0; $j <= $string2_length; ++$j)
|
||||
{
|
||||
$matrix[0][$j] = $j;
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= $string1_length; ++$i)
|
||||
{
|
||||
for ($j = 1; $j <= $string2_length; ++$j)
|
||||
{
|
||||
$cost = substr($string1, $i - 1, 1) == substr($string2, $j - 1, 1) ? 0 : 1;
|
||||
|
||||
$matrix[$i][$j] = min(
|
||||
$matrix[$i - 1][$j] + 1, // deletion
|
||||
$matrix[$i][$j - 1] + 1, // insertion
|
||||
$matrix[$i - 1][$j - 1] + $cost // substitution
|
||||
);
|
||||
|
||||
if ($i > 1 && $j > 1 && (substr($string1, $i - 1, 1) == substr($string2, $j - 2, 1))
|
||||
&& (substr($string1, $i - 2, 1) == substr($string2, $j - 1, 1)))
|
||||
{
|
||||
$matrix[$i][$j] = min(
|
||||
$matrix[$i][$j],
|
||||
$matrix[$i - 2][$j - 2] + $cost // transposition
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $matrix[$string1_length][$string2_length];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts text anchors into links.
|
||||
*
|
||||
* @param string text to auto link
|
||||
* @return string
|
||||
*/
|
||||
public static function auto_link_urls($text)
|
||||
{
|
||||
|
||||
$regex = '~\\b'
|
||||
.'((?:ht|f)tps?://)?' // protocol
|
||||
.'(?:[-a-zA-Z0-9]{1,63}\.)+' // host name
|
||||
.'(?:[0-9]{1,3}|aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)' // tlds
|
||||
.'(?:/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?' // path
|
||||
.'(?:\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?' // query
|
||||
.'(?:#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?' // fragment
|
||||
.'(?=[?.!,;:"]?(?:\s|$))~'; // punctuation and url end
|
||||
|
||||
$result = "";
|
||||
$position = 0;
|
||||
|
||||
while (preg_match($regex, $text, $match, PREG_OFFSET_CAPTURE, $position))
|
||||
{
|
||||
list($url, $url_pos) = $match[0];
|
||||
|
||||
// Add the text before the url
|
||||
$result .= substr($text, $position, $url_pos - $position);
|
||||
|
||||
// Default to http://
|
||||
$full_url = empty($match[1][0]) ? 'http://'.$url : $url;
|
||||
|
||||
// Add the hyperlink.
|
||||
$result .= html::anchor($full_url, $url);
|
||||
|
||||
// New position to start parsing
|
||||
$position = $url_pos + strlen($url);
|
||||
}
|
||||
|
||||
return $result.substr($text, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts text email addresses into links.
|
||||
*
|
||||
* @param string text to auto link
|
||||
* @return string
|
||||
*/
|
||||
public static function auto_link_emails($text)
|
||||
{
|
||||
// Finds all email addresses that are not part of an existing html mailto anchor
|
||||
// Note: The "58;" negative lookbehind prevents matching of existing encoded html mailto anchors
|
||||
// The html entity for a colon (:) is : or : or : etc.
|
||||
if (preg_match_all('~\b(?<!href="mailto:|">|58;)(?!\.)[-+_a-z0-9.]++(?<!\.)@(?![-.])[-a-z0-9.]+(?<!\.)\.[a-z]{2,6}\b~i', $text, $matches))
|
||||
{
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
// Replace each email with an encoded mailto
|
||||
$text = str_replace($match, html::mailto($match), $text);
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically applies <p> and <br /> markup to text. Basically nl2br() on steroids.
|
||||
*
|
||||
* @param string subject
|
||||
* @param boolean convert single linebreaks to <br />
|
||||
* @return string
|
||||
*/
|
||||
public static function auto_p($str, $br = TRUE)
|
||||
{
|
||||
// Trim whitespace
|
||||
if (($str = trim($str)) === '')
|
||||
return '';
|
||||
|
||||
// Standardize newlines
|
||||
$str = str_replace(array("\r\n", "\r"), "\n", $str);
|
||||
|
||||
// Trim whitespace on each line
|
||||
$str = preg_replace('~^[ \t]+~m', '', $str);
|
||||
$str = preg_replace('~[ \t]+$~m', '', $str);
|
||||
|
||||
// The following regexes only need to be executed if the string contains html
|
||||
if ($html_found = (strpos($str, '<') !== FALSE))
|
||||
{
|
||||
// Elements that should not be surrounded by p tags
|
||||
$no_p = '(?:p|div|h[1-6r]|ul|ol|li|blockquote|d[dlt]|pre|t[dhr]|t(?:able|body|foot|head)|c(?:aption|olgroup)|form|s(?:elect|tyle)|a(?:ddress|rea)|ma(?:p|th))';
|
||||
|
||||
// Put at least two linebreaks before and after $no_p elements
|
||||
$str = preg_replace('~^<'.$no_p.'[^>]*+>~im', "\n$0", $str);
|
||||
$str = preg_replace('~</'.$no_p.'\s*+>$~im', "$0\n", $str);
|
||||
}
|
||||
|
||||
// Do the <p> magic!
|
||||
$str = '<p>'.trim($str).'</p>';
|
||||
$str = preg_replace('~\n{2,}~', "</p>\n\n<p>", $str);
|
||||
|
||||
// The following regexes only need to be executed if the string contains html
|
||||
if ($html_found !== FALSE)
|
||||
{
|
||||
// Remove p tags around $no_p elements
|
||||
$str = preg_replace('~<p>(?=</?'.$no_p.'[^>]*+>)~i', '', $str);
|
||||
$str = preg_replace('~(</?'.$no_p.'[^>]*+>)</p>~i', '$1', $str);
|
||||
}
|
||||
|
||||
// Convert single linebreaks to <br />
|
||||
if ($br === TRUE)
|
||||
{
|
||||
$str = preg_replace('~(?<!\n)\n(?!\n)~', "<br />\n", $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human readable sizes.
|
||||
* @see Based on original functions written by:
|
||||
* @see Aidan Lister: http://aidanlister.com/repos/v/function.size_readable.php
|
||||
* @see Quentin Zervaas: http://www.phpriot.com/d/code/strings/filesize-format/
|
||||
*
|
||||
* @param integer size in bytes
|
||||
* @param string a definitive unit
|
||||
* @param string the return string format
|
||||
* @param boolean whether to use SI prefixes or IEC
|
||||
* @return string
|
||||
*/
|
||||
public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE)
|
||||
{
|
||||
// Format string
|
||||
$format = ($format === NULL) ? '%01.2f %s' : (string) $format;
|
||||
|
||||
// IEC prefixes (binary)
|
||||
if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE)
|
||||
{
|
||||
$units = array(__('B'), __('KiB'), __('MiB'), __('GiB'), __('TiB'), __('PiB'));
|
||||
$mod = 1024;
|
||||
}
|
||||
// SI prefixes (decimal)
|
||||
else
|
||||
{
|
||||
$units = array(__('B'), __('kB'), __('MB'), __('GB'), __('TB'), __('PB'));
|
||||
$mod = 1000;
|
||||
}
|
||||
|
||||
// Determine unit to use
|
||||
if (($power = array_search((string) $force_unit, $units)) === FALSE)
|
||||
{
|
||||
$power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0;
|
||||
}
|
||||
|
||||
return sprintf($format, $bytes / pow($mod, $power), $units[$power]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents widow words by inserting a non-breaking space between the last two words.
|
||||
* @see http://www.shauninman.com/archive/2006/08/22/widont_wordpress_plugin
|
||||
*
|
||||
* @param string string to remove widows from
|
||||
* @return string
|
||||
*/
|
||||
public static function widont($str)
|
||||
{
|
||||
$str = rtrim($str);
|
||||
$space = strrpos($str, ' ');
|
||||
|
||||
if ($space !== FALSE)
|
||||
{
|
||||
$str = substr($str, 0, $space).' '.substr($str, $space + 1);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a string contains only 7bit ASCII bytes. This is used to
|
||||
* determine when to use native functions or UTF-8 functions.
|
||||
*
|
||||
* @see http://sourceforge.net/projects/phputf8/
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @copyright (c) 2005 Harry Fuecks
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
|
||||
*
|
||||
* @param string string to check
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_ascii($str)
|
||||
{
|
||||
return is_string($str) AND ! preg_match('/[^\x00-\x7F]/S', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips out device control codes in the ASCII range.
|
||||
*
|
||||
* @see http://sourceforge.net/projects/phputf8/
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @copyright (c) 2005 Harry Fuecks
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
|
||||
*
|
||||
* @param string string to clean
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_ascii_ctrl($str)
|
||||
{
|
||||
return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips out all non-7bit ASCII bytes.
|
||||
*
|
||||
* @see http://sourceforge.net/projects/phputf8/
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @copyright (c) 2005 Harry Fuecks
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
|
||||
*
|
||||
* @param string string to clean
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_non_ascii($str)
|
||||
{
|
||||
return preg_replace('/[^\x00-\x7F]+/S', '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces special/accented UTF-8 characters by ASCII-7 'equivalents'.
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @see http://sourceforge.net/projects/phputf8/
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @copyright (c) 2005 Harry Fuecks
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
|
||||
*
|
||||
* @param string string to transliterate
|
||||
* @param integer -1 lowercase only, +1 uppercase only, 0 both cases
|
||||
* @return string
|
||||
*/
|
||||
public static function transliterate_to_ascii($str, $case = 0)
|
||||
{
|
||||
static $UTF8_LOWER_ACCENTS = NULL;
|
||||
static $UTF8_UPPER_ACCENTS = NULL;
|
||||
|
||||
if ($case <= 0)
|
||||
{
|
||||
if ($UTF8_LOWER_ACCENTS === NULL)
|
||||
{
|
||||
$UTF8_LOWER_ACCENTS = array(
|
||||
'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o',
|
||||
'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k',
|
||||
'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o',
|
||||
'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o',
|
||||
'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c',
|
||||
'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't',
|
||||
'ū' => 'u', 'č' => 'c', 'ö' => 'o', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l',
|
||||
'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z',
|
||||
'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't',
|
||||
'ŗ' => 'r', 'ä' => 'a', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'u', 'ò' => 'o',
|
||||
'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j',
|
||||
'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o',
|
||||
'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g',
|
||||
'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a',
|
||||
'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', 'ı' => 'i',
|
||||
);
|
||||
}
|
||||
|
||||
$str = str_replace(
|
||||
array_keys($UTF8_LOWER_ACCENTS),
|
||||
array_values($UTF8_LOWER_ACCENTS),
|
||||
$str
|
||||
);
|
||||
}
|
||||
|
||||
if ($case >= 0)
|
||||
{
|
||||
if ($UTF8_UPPER_ACCENTS === NULL)
|
||||
{
|
||||
$UTF8_UPPER_ACCENTS = array(
|
||||
'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O',
|
||||
'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', 'Ĕ' => 'E',
|
||||
'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O',
|
||||
'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O',
|
||||
'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C',
|
||||
'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T',
|
||||
'Ū' => 'U', 'Č' => 'C', 'Ö' => 'O', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L',
|
||||
'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z',
|
||||
'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T',
|
||||
'Ŗ' => 'R', 'Ä' => 'A', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'U', 'Ò' => 'O',
|
||||
'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J',
|
||||
'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O',
|
||||
'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G',
|
||||
'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A',
|
||||
'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'İ' => 'I',
|
||||
);
|
||||
}
|
||||
|
||||
$str = str_replace(
|
||||
array_keys($UTF8_UPPER_ACCENTS),
|
||||
array_values($UTF8_UPPER_ACCENTS),
|
||||
$str
|
||||
);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
} // End text
|
159
web_client/system/helpers/upload.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Upload helper class for working with the global $_FILES
|
||||
* array and Validation library.
|
||||
*
|
||||
* $Id: upload.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class upload_Core {
|
||||
|
||||
/**
|
||||
* Save an uploaded file to a new location.
|
||||
*
|
||||
* @param mixed name of $_FILE input or array of upload data
|
||||
* @param string new filename
|
||||
* @param string new directory
|
||||
* @param integer chmod mask
|
||||
* @return string full path to new file
|
||||
*/
|
||||
public static function save($file, $filename = NULL, $directory = NULL, $chmod = 0644)
|
||||
{
|
||||
// Load file data from FILES if not passed as array
|
||||
$file = is_array($file) ? $file : $_FILES[$file];
|
||||
|
||||
if ($filename === NULL)
|
||||
{
|
||||
// Use the default filename, with a timestamp pre-pended
|
||||
$filename = time().$file['name'];
|
||||
}
|
||||
|
||||
if (Kohana::config('upload.remove_spaces') === TRUE)
|
||||
{
|
||||
// Remove spaces from the filename
|
||||
$filename = preg_replace('/\s+/', '_', $filename);
|
||||
}
|
||||
|
||||
if ($directory === NULL)
|
||||
{
|
||||
// Use the pre-configured upload directory
|
||||
$directory = Kohana::config('upload.directory', TRUE);
|
||||
}
|
||||
|
||||
// Make sure the directory ends with a slash
|
||||
$directory = rtrim($directory, '/').'/';
|
||||
|
||||
if ( ! is_dir($directory) AND Kohana::config('upload.create_directories') === TRUE)
|
||||
{
|
||||
// Create the upload directory
|
||||
mkdir($directory, 0777, TRUE);
|
||||
}
|
||||
|
||||
if ( ! is_writable($directory))
|
||||
throw new Kohana_Exception('The upload destination folder, :dir:, does not appear to be writable.', array(':dir:' => $directory));
|
||||
|
||||
if (is_uploaded_file($file['tmp_name']) AND move_uploaded_file($file['tmp_name'], $filename = $directory.$filename))
|
||||
{
|
||||
if ($chmod !== FALSE)
|
||||
{
|
||||
// Set permissions on filename
|
||||
chmod($filename, $chmod);
|
||||
}
|
||||
|
||||
// Return new file path
|
||||
return $filename;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Validation Rules */
|
||||
|
||||
/**
|
||||
* Tests if input data is valid file type, even if no upload is present.
|
||||
*
|
||||
* @param array $_FILES item
|
||||
* @return bool
|
||||
*/
|
||||
public static function valid($file)
|
||||
{
|
||||
return (is_array($file)
|
||||
AND isset($file['error'])
|
||||
AND isset($file['name'])
|
||||
AND isset($file['type'])
|
||||
AND isset($file['tmp_name'])
|
||||
AND isset($file['size']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if input data has valid upload data.
|
||||
*
|
||||
* @param array $_FILES item
|
||||
* @return bool
|
||||
*/
|
||||
public static function required(array $file)
|
||||
{
|
||||
return (isset($file['tmp_name'])
|
||||
AND isset($file['error'])
|
||||
AND is_uploaded_file($file['tmp_name'])
|
||||
AND (int) $file['error'] === UPLOAD_ERR_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation rule to test if an uploaded file is allowed by extension.
|
||||
*
|
||||
* @param array $_FILES item
|
||||
* @param array allowed file extensions
|
||||
* @return bool
|
||||
*/
|
||||
public static function type(array $file, array $allowed_types)
|
||||
{
|
||||
if ((int) $file['error'] !== UPLOAD_ERR_OK)
|
||||
return TRUE;
|
||||
|
||||
// Get the default extension of the file
|
||||
$extension = strtolower(substr(strrchr($file['name'], '.'), 1));
|
||||
|
||||
// Make sure there is an extension and that the extension is allowed
|
||||
return ( ! empty($extension) AND in_array($extension, $allowed_types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation rule to test if an uploaded file is allowed by file size.
|
||||
* File sizes are defined as: SB, where S is the size (1, 15, 300, etc) and
|
||||
* B is the byte modifier: (B)ytes, (K)ilobytes, (M)egabytes, (G)igabytes.
|
||||
* Eg: to limit the size to 1MB or less, you would use "1M".
|
||||
*
|
||||
* @param array $_FILES item
|
||||
* @param array maximum file size
|
||||
* @return bool
|
||||
*/
|
||||
public static function size(array $file, array $size)
|
||||
{
|
||||
if ((int) $file['error'] !== UPLOAD_ERR_OK)
|
||||
return TRUE;
|
||||
|
||||
// Only one size is allowed
|
||||
$size = strtoupper($size[0]);
|
||||
|
||||
if ( ! preg_match('/[0-9]++[BKMG]/', $size))
|
||||
return FALSE;
|
||||
|
||||
// Make the size into a power of 1024
|
||||
switch (substr($size, -1))
|
||||
{
|
||||
case 'G': $size = intval($size) * pow(1024, 3); break;
|
||||
case 'M': $size = intval($size) * pow(1024, 2); break;
|
||||
case 'K': $size = intval($size) * pow(1024, 1); break;
|
||||
default: $size = intval($size); break;
|
||||
}
|
||||
|
||||
// Test that the file is under or equal to the max size
|
||||
return ($file['size'] <= $size);
|
||||
}
|
||||
|
||||
} // End upload
|
264
web_client/system/helpers/url.php
Normal file
@ -0,0 +1,264 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* URL helper class.
|
||||
*
|
||||
* $Id: url.php 4685 2009-11-30 21:24:06Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class url_Core {
|
||||
|
||||
/**
|
||||
* Fetches the current URI.
|
||||
*
|
||||
* @param boolean include the query string
|
||||
* @param boolean include the suffix
|
||||
* @return string
|
||||
*/
|
||||
public static function current($qs = FALSE, $suffix = FALSE)
|
||||
{
|
||||
$uri = ($qs === TRUE) ? Router::$complete_uri : Router::$current_uri;
|
||||
|
||||
return ($suffix === TRUE) ? $uri.Kohana::config('core.url_suffix') : $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base URL, with or without the index page.
|
||||
*
|
||||
* If protocol (and core.site_protocol) and core.site_domain are both empty,
|
||||
* then
|
||||
*
|
||||
* @param boolean include the index page
|
||||
* @param boolean non-default protocol
|
||||
* @return string
|
||||
*/
|
||||
public static function base($index = FALSE, $protocol = FALSE)
|
||||
{
|
||||
if ($protocol == FALSE)
|
||||
{
|
||||
// Use the default configured protocol
|
||||
$protocol = Kohana::config('core.site_protocol');
|
||||
}
|
||||
|
||||
// Load the site domain
|
||||
$site_domain = (string) Kohana::config('core.site_domain', TRUE);
|
||||
|
||||
if ($protocol == FALSE)
|
||||
{
|
||||
if ($site_domain === '' OR $site_domain[0] === '/')
|
||||
{
|
||||
// Use the configured site domain
|
||||
$base_url = $site_domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Guess the protocol to provide full http://domain/path URL
|
||||
$base_url = ((empty($_SERVER['HTTPS']) OR $_SERVER['HTTPS'] === 'off') ? 'http' : 'https').'://'.$site_domain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($site_domain === '' OR $site_domain[0] === '/')
|
||||
{
|
||||
// Guess the server name if the domain starts with slash
|
||||
$base_url = $protocol.'://'.$_SERVER['HTTP_HOST'].$site_domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the configured site domain
|
||||
$base_url = $protocol.'://'.$site_domain;
|
||||
}
|
||||
}
|
||||
|
||||
if ($index === TRUE AND $index = Kohana::config('core.index_page'))
|
||||
{
|
||||
// Append the index page
|
||||
$base_url = $base_url.$index;
|
||||
}
|
||||
|
||||
// Force a slash on the end of the URL
|
||||
return rtrim($base_url, '/').'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches an absolute site URL based on a URI segment.
|
||||
*
|
||||
* @param string site URI to convert
|
||||
* @param string non-default protocol
|
||||
* @return string
|
||||
*/
|
||||
public static function site($uri = '', $protocol = FALSE)
|
||||
{
|
||||
if ($path = trim(parse_url($uri, PHP_URL_PATH), '/'))
|
||||
{
|
||||
// Add path suffix
|
||||
$path .= Kohana::config('core.url_suffix');
|
||||
}
|
||||
|
||||
if ($query = parse_url($uri, PHP_URL_QUERY))
|
||||
{
|
||||
// ?query=string
|
||||
$query = '?'.$query;
|
||||
}
|
||||
|
||||
if ($fragment = parse_url($uri, PHP_URL_FRAGMENT))
|
||||
{
|
||||
// #fragment
|
||||
$fragment = '#'.$fragment;
|
||||
}
|
||||
|
||||
// Concat the URL
|
||||
return url::base(TRUE, $protocol).$path.$query.$fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL to a file. Absolute filenames and relative filenames
|
||||
* are allowed.
|
||||
*
|
||||
* @param string filename
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
*/
|
||||
public static function file($file, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL to the filename
|
||||
$file = url::base($index).$file;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges an array of arguments with the current URI and query string to
|
||||
* overload, instead of replace, the current query string.
|
||||
*
|
||||
* @param array associative array of arguments
|
||||
* @return string
|
||||
*/
|
||||
public static function merge(array $arguments)
|
||||
{
|
||||
if ($_GET === $arguments)
|
||||
{
|
||||
$query = Router::$query_string;
|
||||
}
|
||||
elseif ($query = http_build_query(array_merge($_GET, $arguments)))
|
||||
{
|
||||
$query = '?'.$query;
|
||||
}
|
||||
|
||||
// Return the current URI with the arguments merged into the query string
|
||||
return Router::$current_uri.$query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a phrase to a URL-safe title.
|
||||
*
|
||||
* @param string phrase to convert
|
||||
* @param string word separator (- or _)
|
||||
* @param boolean transliterate to ASCII
|
||||
* @return string
|
||||
*/
|
||||
public static function title($title, $separator = '-', $ascii_only = FALSE)
|
||||
{
|
||||
$separator = ($separator === '-') ? '-' : '_';
|
||||
|
||||
if ($ascii_only === TRUE)
|
||||
{
|
||||
// Replace accented characters by their unaccented equivalents
|
||||
$title = text::transliterate_to_ascii($title);
|
||||
|
||||
// Remove all characters that are not the separator, a-z, 0-9, or whitespace
|
||||
$title = preg_replace('/[^'.$separator.'a-z0-9\s]+/', '', strtolower($title));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove all characters that are not the separator, letters, numbers, or whitespace
|
||||
$title = preg_replace('/[^'.$separator.'\pL\pN\s]+/u', '', mb_strtolower($title));
|
||||
}
|
||||
|
||||
// Replace all separator characters and whitespace by a single separator
|
||||
$title = preg_replace('/['.$separator.'\s]+/', $separator, $title);
|
||||
|
||||
// Trim separators from the beginning and end
|
||||
return trim($title, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a page redirect header and runs the system.redirect Event.
|
||||
*
|
||||
* @param mixed string site URI or URL to redirect to, or array of strings if method is 300
|
||||
* @param string HTTP method of redirect
|
||||
* @return void
|
||||
*/
|
||||
public static function redirect($uri = '', $method = '302')
|
||||
{
|
||||
if (Event::has_run('system.send_headers'))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$codes = array
|
||||
(
|
||||
'refresh' => 'Refresh',
|
||||
'300' => 'Multiple Choices',
|
||||
'301' => 'Moved Permanently',
|
||||
'302' => 'Found',
|
||||
'303' => 'See Other',
|
||||
'304' => 'Not Modified',
|
||||
'305' => 'Use Proxy',
|
||||
'307' => 'Temporary Redirect'
|
||||
);
|
||||
|
||||
// Validate the method and default to 302
|
||||
$method = isset($codes[$method]) ? (string) $method : '302';
|
||||
|
||||
if ($method === '300')
|
||||
{
|
||||
$uri = (array) $uri;
|
||||
|
||||
$output = '<ul>';
|
||||
foreach ($uri as $link)
|
||||
{
|
||||
$output .= '<li>'.html::anchor($link).'</li>';
|
||||
}
|
||||
$output .= '</ul>';
|
||||
|
||||
// The first URI will be used for the Location header
|
||||
$uri = $uri[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$output = '<p>'.html::anchor($uri).'</p>';
|
||||
}
|
||||
|
||||
// Run the redirect event
|
||||
Event::run('system.redirect', $uri);
|
||||
|
||||
if (strpos($uri, '://') === FALSE)
|
||||
{
|
||||
// HTTP headers expect absolute URLs
|
||||
$uri = url::site($uri, request::protocol());
|
||||
}
|
||||
|
||||
if ($method === 'refresh')
|
||||
{
|
||||
header('Refresh: 0; url='.$uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
header('HTTP/1.1 '.$method.' '.$codes[$method]);
|
||||
header('Location: '.$uri);
|
||||
}
|
||||
|
||||
// We are about to exit, so run the send_headers event
|
||||
Event::run('system.send_headers');
|
||||
|
||||
exit('<h1>'.$method.' - '.$codes[$method].'</h1>'.$output);
|
||||
}
|
||||
|
||||
} // End url
|
746
web_client/system/helpers/utf8.php
Normal file
@ -0,0 +1,746 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* A port of phputf8 to a unified file/class.
|
||||
*
|
||||
* This file is licensed differently from the rest of Kohana. As a port of
|
||||
* phputf8, which is LGPL software, this file is released under the LGPL.
|
||||
*
|
||||
* PCRE needs to be compiled with UTF-8 support (--enable-utf8).
|
||||
* Support for Unicode properties is highly recommended (--enable-unicode-properties).
|
||||
* @see http://php.net/manual/reference.pcre.pattern.modifiers.php
|
||||
*
|
||||
* string functions.
|
||||
* @see http://php.net/mbstring
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @copyright (c) 2005 Harry Fuecks
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
|
||||
*/
|
||||
|
||||
class utf8 {
|
||||
|
||||
/**
|
||||
* Replaces text within a portion of a UTF-8 string.
|
||||
* @see http://php.net/substr_replace
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string replacement string
|
||||
* @param integer offset
|
||||
* @return string
|
||||
*/
|
||||
public static function substr_replace($str, $replacement, $offset, $length = NULL)
|
||||
{
|
||||
if (text::is_ascii($str))
|
||||
return ($length === NULL) ? substr_replace($str, $replacement, $offset) : substr_replace($str, $replacement, $offset, $length);
|
||||
|
||||
$length = ($length === NULL) ? mb_strlen($str) : (int) $length;
|
||||
preg_match_all('/./us', $str, $str_array);
|
||||
preg_match_all('/./us', $replacement, $replacement_array);
|
||||
|
||||
array_splice($str_array[0], $offset, $length, $replacement_array[0]);
|
||||
return implode('', $str_array[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a UTF-8 string's first character uppercase.
|
||||
* @see http://php.net/ucfirst
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string mixed case string
|
||||
* @return string
|
||||
*/
|
||||
public static function ucfirst($str)
|
||||
{
|
||||
if (text::is_ascii($str))
|
||||
return ucfirst($str);
|
||||
|
||||
preg_match('/^(.?)(.*)$/us', $str, $matches);
|
||||
return mb_strtoupper($matches[1]).$matches[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive UTF-8 string comparison.
|
||||
* @see http://php.net/strcasecmp
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string string to compare
|
||||
* @param string string to compare
|
||||
* @return integer less than 0 if str1 is less than str2
|
||||
* @return integer greater than 0 if str1 is greater than str2
|
||||
* @return integer 0 if they are equal
|
||||
*/
|
||||
public static function strcasecmp($str1, $str2)
|
||||
{
|
||||
if (text::is_ascii($str1) AND text::is_ascii($str2))
|
||||
return strcasecmp($str1, $str2);
|
||||
|
||||
$str1 = mb_strtolower($str1);
|
||||
$str2 = mb_strtolower($str2);
|
||||
return strcmp($str1, $str2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string or an array with all occurrences of search in subject (ignoring case).
|
||||
* replaced with the given replace value.
|
||||
* @see http://php.net/str_ireplace
|
||||
*
|
||||
* @note It's not fast and gets slower if $search and/or $replace are arrays.
|
||||
* @author Harry Fuecks <hfuecks@gmail.com
|
||||
*
|
||||
* @param string|array text to replace
|
||||
* @param string|array replacement text
|
||||
* @param string|array subject text
|
||||
* @param integer number of matched and replaced needles will be returned via this parameter which is passed by reference
|
||||
* @return string if the input was a string
|
||||
* @return array if the input was an array
|
||||
*/
|
||||
public static function str_ireplace($search, $replace, $str, & $count = NULL)
|
||||
{
|
||||
if (text::is_ascii($search) AND text::is_ascii($replace) AND text::is_ascii($str))
|
||||
return str_ireplace($search, $replace, $str, $count);
|
||||
|
||||
if (is_array($str))
|
||||
{
|
||||
foreach ($str as $key => $val)
|
||||
{
|
||||
$str[$key] = utf8::str_ireplace($search, $replace, $val, $count);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
if (is_array($search))
|
||||
{
|
||||
$keys = array_keys($search);
|
||||
|
||||
foreach ($keys as $k)
|
||||
{
|
||||
if (is_array($replace))
|
||||
{
|
||||
if (array_key_exists($k, $replace))
|
||||
{
|
||||
$str = utf8::str_ireplace($search[$k], $replace[$k], $str, $count);
|
||||
}
|
||||
else
|
||||
{
|
||||
$str = utf8::str_ireplace($search[$k], '', $str, $count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$str = utf8::str_ireplace($search[$k], $replace, $str, $count);
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
$search = mb_strtolower($search);
|
||||
$str_lower = mb_strtolower($str);
|
||||
|
||||
$total_matched_strlen = 0;
|
||||
$i = 0;
|
||||
|
||||
while (preg_match('/(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches))
|
||||
{
|
||||
$matched_strlen = strlen($matches[0]);
|
||||
$str_lower = substr($str_lower, $matched_strlen);
|
||||
|
||||
$offset = $total_matched_strlen + strlen($matches[1]) + ($i * (strlen($replace) - 1));
|
||||
$str = substr_replace($str, $replace, $offset, strlen($search));
|
||||
|
||||
$total_matched_strlen += $matched_strlen;
|
||||
$i++;
|
||||
}
|
||||
|
||||
$count += $i;
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insenstive UTF-8 version of strstr. Returns all of input string
|
||||
* from the first occurrence of needle to the end.
|
||||
* @see http://php.net/stristr
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string needle
|
||||
* @return string matched substring if found
|
||||
* @return boolean FALSE if the substring was not found
|
||||
*/
|
||||
public static function stristr($str, $search)
|
||||
{
|
||||
if (text::is_ascii($str) AND text::is_ascii($search))
|
||||
return stristr($str, $search);
|
||||
|
||||
if ($search == '')
|
||||
return $str;
|
||||
|
||||
$str_lower = mb_strtolower($str);
|
||||
$search_lower = mb_strtolower($search);
|
||||
|
||||
preg_match('/^(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches);
|
||||
|
||||
if (isset($matches[1]))
|
||||
return substr($str, strlen($matches[1]));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the length of the initial segment matching mask.
|
||||
* @see http://php.net/strspn
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string mask for search
|
||||
* @param integer start position of the string to examine
|
||||
* @param integer length of the string to examine
|
||||
* @return integer length of the initial segment that contains characters in the mask
|
||||
*/
|
||||
public static function strspn($str, $mask, $offset = NULL, $length = NULL)
|
||||
{
|
||||
if ($str == '' OR $mask == '')
|
||||
return 0;
|
||||
|
||||
if (text::is_ascii($str) AND text::is_ascii($mask))
|
||||
return ($offset === NULL) ? strspn($str, $mask) : (($length === NULL) ? strspn($str, $mask, $offset) : strspn($str, $mask, $offset, $length));
|
||||
|
||||
if ($offset !== NULL OR $length !== NULL)
|
||||
{
|
||||
$str = mb_substr($str, $offset, $length);
|
||||
}
|
||||
|
||||
// Escape these characters: - [ ] . : \ ^ /
|
||||
// The . and : are escaped to prevent possible warnings about POSIX regex elements
|
||||
$mask = preg_replace('#[-[\].:\\\\^/]#', '\\\\$0', $mask);
|
||||
preg_match('/^[^'.$mask.']+/u', $str, $matches);
|
||||
|
||||
return isset($matches[0]) ? mb_strlen($matches[0]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the length of the initial segment not matching mask.
|
||||
* @see http://php.net/strcspn
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string mask for search
|
||||
* @param integer start position of the string to examine
|
||||
* @param integer length of the string to examine
|
||||
* @return integer length of the initial segment that contains characters not in the mask
|
||||
*/
|
||||
public static function strcspn($str, $mask, $offset = NULL, $length = NULL)
|
||||
{
|
||||
if ($str == '' OR $mask == '')
|
||||
return 0;
|
||||
|
||||
if (text::is_ascii($str) AND text::is_ascii($mask))
|
||||
return ($offset === NULL) ? strcspn($str, $mask) : (($length === NULL) ? strcspn($str, $mask, $offset) : strcspn($str, $mask, $offset, $length));
|
||||
|
||||
if ($str !== NULL OR $length !== NULL)
|
||||
{
|
||||
$str = mb_substr($str, $offset, $length);
|
||||
}
|
||||
|
||||
// Escape these characters: - [ ] . : \ ^ /
|
||||
// The . and : are escaped to prevent possible warnings about POSIX regex elements
|
||||
$mask = preg_replace('#[-[\].:\\\\^/]#', '\\\\$0', $mask);
|
||||
preg_match('/^[^'.$mask.']+/u', $str, $matches);
|
||||
|
||||
return isset($matches[0]) ? mb_strlen($matches[0]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads a UTF-8 string to a certain length with another string.
|
||||
* @see http://php.net/str_pad
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param integer desired string length after padding
|
||||
* @param string string to use as padding
|
||||
* @param string padding type: STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH
|
||||
* @return string
|
||||
*/
|
||||
public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT)
|
||||
{
|
||||
if (text::is_ascii($str) AND text::is_ascii($pad_str))
|
||||
{
|
||||
return str_pad($str, $final_str_length, $pad_str, $pad_type);
|
||||
}
|
||||
|
||||
$str_length = mb_strlen($str);
|
||||
|
||||
if ($final_str_length <= 0 OR $final_str_length <= $str_length)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
$pad_str_length = mb_strlen($pad_str);
|
||||
$pad_length = $final_str_length - $str_length;
|
||||
|
||||
if ($pad_type == STR_PAD_RIGHT)
|
||||
{
|
||||
$repeat = ceil($pad_length / $pad_str_length);
|
||||
return mb_substr($str.str_repeat($pad_str, $repeat), 0, $final_str_length);
|
||||
}
|
||||
|
||||
if ($pad_type == STR_PAD_LEFT)
|
||||
{
|
||||
$repeat = ceil($pad_length / $pad_str_length);
|
||||
return mb_substr(str_repeat($pad_str, $repeat), 0, floor($pad_length)).$str;
|
||||
}
|
||||
|
||||
if ($pad_type == STR_PAD_BOTH)
|
||||
{
|
||||
$pad_length /= 2;
|
||||
$pad_length_left = floor($pad_length);
|
||||
$pad_length_right = ceil($pad_length);
|
||||
$repeat_left = ceil($pad_length_left / $pad_str_length);
|
||||
$repeat_right = ceil($pad_length_right / $pad_str_length);
|
||||
|
||||
$pad_left = mb_substr(str_repeat($pad_str, $repeat_left), 0, $pad_length_left);
|
||||
$pad_right = mb_substr(str_repeat($pad_str, $repeat_right), 0, $pad_length_left);
|
||||
return $pad_left.$str.$pad_right;
|
||||
}
|
||||
|
||||
trigger_error('utf8::str_pad: Unknown padding type (' . $pad_type . ')', E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string to an array.
|
||||
* @see http://php.net/str_split
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string input string
|
||||
* @param integer maximum length of each chunk
|
||||
* @return array
|
||||
*/
|
||||
public static function str_split($str, $split_length = 1)
|
||||
{
|
||||
$split_length = (int) $split_length;
|
||||
|
||||
if (text::is_ascii($str))
|
||||
{
|
||||
return str_split($str, $split_length);
|
||||
}
|
||||
|
||||
if ($split_length < 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mb_strlen($str) <= $split_length)
|
||||
{
|
||||
return array($str);
|
||||
}
|
||||
|
||||
preg_match_all('/.{'.$split_length.'}|[^\x00]{1,'.$split_length.'}$/us', $str, $matches);
|
||||
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses a UTF-8 string.
|
||||
* @see http://php.net/strrev
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string string to be reversed
|
||||
* @return string
|
||||
*/
|
||||
public static function strrev($str)
|
||||
{
|
||||
if (text::is_ascii($str))
|
||||
return strrev($str);
|
||||
|
||||
preg_match_all('/./us', $str, $matches);
|
||||
return implode('', array_reverse($matches[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips whitespace (or other UTF-8 characters) from the beginning and
|
||||
* end of a string.
|
||||
* @see http://php.net/trim
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string string of characters to remove
|
||||
* @return string
|
||||
*/
|
||||
public static function trim($str, $charlist = NULL)
|
||||
{
|
||||
if ($charlist === NULL)
|
||||
return trim($str);
|
||||
|
||||
return utf8::ltrim(utf8::rtrim($str, $charlist), $charlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips whitespace (or other UTF-8 characters) from the beginning of a string.
|
||||
* @see http://php.net/ltrim
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string string of characters to remove
|
||||
* @return string
|
||||
*/
|
||||
public static function ltrim($str, $charlist = NULL)
|
||||
{
|
||||
if ($charlist === NULL)
|
||||
return ltrim($str);
|
||||
|
||||
if (text::is_ascii($charlist))
|
||||
return ltrim($str, $charlist);
|
||||
|
||||
$charlist = preg_replace('#[-\[\]:\\\\^/]#', '\\\\$0', $charlist);
|
||||
|
||||
return preg_replace('/^['.$charlist.']+/u', '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips whitespace (or other UTF-8 characters) from the end of a string.
|
||||
* @see http://php.net/rtrim
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
*
|
||||
* @param string input string
|
||||
* @param string string of characters to remove
|
||||
* @return string
|
||||
*/
|
||||
public static function rtrim($str, $charlist = NULL)
|
||||
{
|
||||
if ($charlist === NULL)
|
||||
return rtrim($str);
|
||||
|
||||
if (text::is_ascii($charlist))
|
||||
return rtrim($str, $charlist);
|
||||
|
||||
$charlist = preg_replace('#[-\[\]:\\\\^/]#', '\\\\$0', $charlist);
|
||||
|
||||
return preg_replace('/['.$charlist.']++$/uD', '', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unicode ordinal for a character.
|
||||
* @see http://php.net/ord
|
||||
*
|
||||
* @author Harry Fuecks <hfuecks@gmail.com>
|
||||
*
|
||||
* @param string UTF-8 encoded character
|
||||
* @return integer
|
||||
*/
|
||||
public static function ord($chr)
|
||||
{
|
||||
$ord0 = ord($chr);
|
||||
|
||||
if ($ord0 >= 0 AND $ord0 <= 127)
|
||||
{
|
||||
return $ord0;
|
||||
}
|
||||
|
||||
if ( ! isset($chr[1]))
|
||||
{
|
||||
trigger_error('Short sequence - at least 2 bytes expected, only 1 seen', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$ord1 = ord($chr[1]);
|
||||
|
||||
if ($ord0 >= 192 AND $ord0 <= 223)
|
||||
{
|
||||
return ($ord0 - 192) * 64 + ($ord1 - 128);
|
||||
}
|
||||
|
||||
if ( ! isset($chr[2]))
|
||||
{
|
||||
trigger_error('Short sequence - at least 3 bytes expected, only 2 seen', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$ord2 = ord($chr[2]);
|
||||
|
||||
if ($ord0 >= 224 AND $ord0 <= 239)
|
||||
{
|
||||
return ($ord0 - 224) * 4096 + ($ord1 - 128) * 64 + ($ord2 - 128);
|
||||
}
|
||||
|
||||
if ( ! isset($chr[3]))
|
||||
{
|
||||
trigger_error('Short sequence - at least 4 bytes expected, only 3 seen', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$ord3 = ord($chr[3]);
|
||||
|
||||
if ($ord0 >= 240 AND $ord0 <= 247)
|
||||
{
|
||||
return ($ord0 - 240) * 262144 + ($ord1 - 128) * 4096 + ($ord2-128) * 64 + ($ord3 - 128);
|
||||
}
|
||||
|
||||
if ( ! isset($chr[4]))
|
||||
{
|
||||
trigger_error('Short sequence - at least 5 bytes expected, only 4 seen', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$ord4 = ord($chr[4]);
|
||||
|
||||
if ($ord0 >= 248 AND $ord0 <= 251)
|
||||
{
|
||||
return ($ord0 - 248) * 16777216 + ($ord1-128) * 262144 + ($ord2 - 128) * 4096 + ($ord3 - 128) * 64 + ($ord4 - 128);
|
||||
}
|
||||
|
||||
if ( ! isset($chr[5]))
|
||||
{
|
||||
trigger_error('Short sequence - at least 6 bytes expected, only 5 seen', E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($ord0 >= 252 AND $ord0 <= 253)
|
||||
{
|
||||
return ($ord0 - 252) * 1073741824 + ($ord1 - 128) * 16777216 + ($ord2 - 128) * 262144 + ($ord3 - 128) * 4096 + ($ord4 - 128) * 64 + (ord($chr[5]) - 128);
|
||||
}
|
||||
|
||||
if ($ord0 >= 254 AND $ord0 <= 255)
|
||||
{
|
||||
trigger_error('Invalid UTF-8 with surrogate ordinal '.$ord0, E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an UTF-8 string and returns an array of ints representing the Unicode characters.
|
||||
* Astral planes are supported i.e. the ints in the output can be > 0xFFFF.
|
||||
* Occurrances of the BOM are ignored. Surrogates are not allowed.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
* The Initial Developer of the Original Code is Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer.
|
||||
* Ported to PHP by Henri Sivonen <hsivonen@iki.fi>, see http://hsivonen.iki.fi/php-utf8/.
|
||||
* Slight modifications to fit with phputf8 library by Harry Fuecks <hfuecks@gmail.com>.
|
||||
*
|
||||
* @param string UTF-8 encoded string
|
||||
* @return array unicode code points
|
||||
* @return boolean FALSE if the string is invalid
|
||||
*/
|
||||
public static function to_unicode($str)
|
||||
{
|
||||
$mState = 0; // cached expected number of octets after the current octet until the beginning of the next UTF8 character sequence
|
||||
$mUcs4 = 0; // cached Unicode character
|
||||
$mBytes = 1; // cached expected number of octets in the current sequence
|
||||
|
||||
$out = array();
|
||||
|
||||
$len = strlen($str);
|
||||
|
||||
for ($i = 0; $i < $len; $i++)
|
||||
{
|
||||
$in = ord($str[$i]);
|
||||
|
||||
if ($mState == 0)
|
||||
{
|
||||
// When mState is zero we expect either a US-ASCII character or a
|
||||
// multi-octet sequence.
|
||||
if (0 == (0x80 & $in))
|
||||
{
|
||||
// US-ASCII, pass straight through.
|
||||
$out[] = $in;
|
||||
$mBytes = 1;
|
||||
}
|
||||
elseif (0xC0 == (0xE0 & $in))
|
||||
{
|
||||
// First octet of 2 octet sequence
|
||||
$mUcs4 = $in;
|
||||
$mUcs4 = ($mUcs4 & 0x1F) << 6;
|
||||
$mState = 1;
|
||||
$mBytes = 2;
|
||||
}
|
||||
elseif (0xE0 == (0xF0 & $in))
|
||||
{
|
||||
// First octet of 3 octet sequence
|
||||
$mUcs4 = $in;
|
||||
$mUcs4 = ($mUcs4 & 0x0F) << 12;
|
||||
$mState = 2;
|
||||
$mBytes = 3;
|
||||
}
|
||||
elseif (0xF0 == (0xF8 & $in))
|
||||
{
|
||||
// First octet of 4 octet sequence
|
||||
$mUcs4 = $in;
|
||||
$mUcs4 = ($mUcs4 & 0x07) << 18;
|
||||
$mState = 3;
|
||||
$mBytes = 4;
|
||||
}
|
||||
elseif (0xF8 == (0xFC & $in))
|
||||
{
|
||||
// First octet of 5 octet sequence.
|
||||
//
|
||||
// This is illegal because the encoded codepoint must be either
|
||||
// (a) not the shortest form or
|
||||
// (b) outside the Unicode range of 0-0x10FFFF.
|
||||
// Rather than trying to resynchronize, we will carry on until the end
|
||||
// of the sequence and let the later error handling code catch it.
|
||||
$mUcs4 = $in;
|
||||
$mUcs4 = ($mUcs4 & 0x03) << 24;
|
||||
$mState = 4;
|
||||
$mBytes = 5;
|
||||
}
|
||||
elseif (0xFC == (0xFE & $in))
|
||||
{
|
||||
// First octet of 6 octet sequence, see comments for 5 octet sequence.
|
||||
$mUcs4 = $in;
|
||||
$mUcs4 = ($mUcs4 & 1) << 30;
|
||||
$mState = 5;
|
||||
$mBytes = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current octet is neither in the US-ASCII range nor a legal first octet of a multi-octet sequence.
|
||||
trigger_error('utf8::to_unicode: Illegal sequence identifier in UTF-8 at byte '.$i, E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When mState is non-zero, we expect a continuation of the multi-octet sequence
|
||||
if (0x80 == (0xC0 & $in))
|
||||
{
|
||||
// Legal continuation
|
||||
$shift = ($mState - 1) * 6;
|
||||
$tmp = $in;
|
||||
$tmp = ($tmp & 0x0000003F) << $shift;
|
||||
$mUcs4 |= $tmp;
|
||||
|
||||
// End of the multi-octet sequence. mUcs4 now contains the final Unicode codepoint to be output
|
||||
if (0 == --$mState)
|
||||
{
|
||||
// Check for illegal sequences and codepoints
|
||||
|
||||
// From Unicode 3.1, non-shortest form is illegal
|
||||
if (((2 == $mBytes) AND ($mUcs4 < 0x0080)) OR
|
||||
((3 == $mBytes) AND ($mUcs4 < 0x0800)) OR
|
||||
((4 == $mBytes) AND ($mUcs4 < 0x10000)) OR
|
||||
(4 < $mBytes) OR
|
||||
// From Unicode 3.2, surrogate characters are illegal
|
||||
(($mUcs4 & 0xFFFFF800) == 0xD800) OR
|
||||
// Codepoints outside the Unicode range are illegal
|
||||
($mUcs4 > 0x10FFFF))
|
||||
{
|
||||
trigger_error('utf8::to_unicode: Illegal sequence or codepoint in UTF-8 at byte '.$i, E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0xFEFF != $mUcs4)
|
||||
{
|
||||
// BOM is legal but we don't want to output it
|
||||
$out[] = $mUcs4;
|
||||
}
|
||||
|
||||
// Initialize UTF-8 cache
|
||||
$mState = 0;
|
||||
$mUcs4 = 0;
|
||||
$mBytes = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ((0xC0 & (*in) != 0x80) AND (mState != 0))
|
||||
// Incomplete multi-octet sequence
|
||||
trigger_error('utf8::to_unicode: Incomplete multi-octet sequence in UTF-8 at byte '.$i, E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an array of ints representing the Unicode characters and returns a UTF-8 string.
|
||||
* Astral planes are supported i.e. the ints in the input can be > 0xFFFF.
|
||||
* Occurrances of the BOM are ignored. Surrogates are not allowed.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
* The Initial Developer of the Original Code is Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer.
|
||||
* Ported to PHP by Henri Sivonen <hsivonen@iki.fi>, see http://hsivonen.iki.fi/php-utf8/.
|
||||
* Slight modifications to fit with phputf8 library by Harry Fuecks <hfuecks@gmail.com>.
|
||||
*
|
||||
* @param array unicode code points representing a string
|
||||
* @return string utf8 string of characters
|
||||
* @return boolean FALSE if a code point cannot be found
|
||||
*/
|
||||
public static function from_unicode($arr)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
$keys = array_keys($arr);
|
||||
|
||||
foreach ($keys as $k)
|
||||
{
|
||||
// ASCII range (including control chars)
|
||||
if (($arr[$k] >= 0) AND ($arr[$k] <= 0x007f))
|
||||
{
|
||||
echo chr($arr[$k]);
|
||||
}
|
||||
// 2 byte sequence
|
||||
elseif ($arr[$k] <= 0x07ff)
|
||||
{
|
||||
echo chr(0xc0 | ($arr[$k] >> 6));
|
||||
echo chr(0x80 | ($arr[$k] & 0x003f));
|
||||
}
|
||||
// Byte order mark (skip)
|
||||
elseif ($arr[$k] == 0xFEFF)
|
||||
{
|
||||
// nop -- zap the BOM
|
||||
}
|
||||
// Test for illegal surrogates
|
||||
elseif ($arr[$k] >= 0xD800 AND $arr[$k] <= 0xDFFF)
|
||||
{
|
||||
// Found a surrogate
|
||||
trigger_error('utf8::from_unicode: Illegal surrogate at index: '.$k.', value: '.$arr[$k], E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
// 3 byte sequence
|
||||
elseif ($arr[$k] <= 0xffff)
|
||||
{
|
||||
echo chr(0xe0 | ($arr[$k] >> 12));
|
||||
echo chr(0x80 | (($arr[$k] >> 6) & 0x003f));
|
||||
echo chr(0x80 | ($arr[$k] & 0x003f));
|
||||
}
|
||||
// 4 byte sequence
|
||||
elseif ($arr[$k] <= 0x10ffff)
|
||||
{
|
||||
echo chr(0xf0 | ($arr[$k] >> 18));
|
||||
echo chr(0x80 | (($arr[$k] >> 12) & 0x3f));
|
||||
echo chr(0x80 | (($arr[$k] >> 6) & 0x3f));
|
||||
echo chr(0x80 | ($arr[$k] & 0x3f));
|
||||
}
|
||||
// Out of range
|
||||
else
|
||||
{
|
||||
trigger_error('utf8::from_unicode: Codepoint out of Unicode range at index: '.$k.', value: '.$arr[$k], E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$result = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $result;
|
||||
}
|
||||
|
||||
} // End utf8
|
366
web_client/system/helpers/valid.php
Normal file
@ -0,0 +1,366 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Validation helper class.
|
||||
*
|
||||
* $Id: valid.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class valid_Core {
|
||||
|
||||
/**
|
||||
* Validate email, commonly used characters only
|
||||
*
|
||||
* @param string email address
|
||||
* @return boolean
|
||||
*/
|
||||
public static function email($email)
|
||||
{
|
||||
return (bool) preg_match('/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD', (string) $email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the domain of an email address by checking if the domain has a
|
||||
* valid MX record.
|
||||
*
|
||||
* @param string email address
|
||||
* @return boolean
|
||||
*/
|
||||
public static function email_domain($email)
|
||||
{
|
||||
// If we can't prove the domain is invalid, consider it valid
|
||||
// Note: checkdnsrr() is not implemented on Windows platforms
|
||||
if ( ! function_exists('checkdnsrr'))
|
||||
return TRUE;
|
||||
|
||||
// Check if the email domain has a valid MX record
|
||||
return (bool) checkdnsrr(preg_replace('/^[^@]+@/', '', $email), 'MX');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate email, RFC compliant version
|
||||
* Note: This function is LESS strict than valid_email. Choose carefully.
|
||||
*
|
||||
* @see Originally by Cal Henderson, modified to fit Kohana syntax standards:
|
||||
* @see http://www.iamcal.com/publish/articles/php/parsing_email/
|
||||
* @see http://www.w3.org/Protocols/rfc822/
|
||||
*
|
||||
* @param string email address
|
||||
* @return boolean
|
||||
*/
|
||||
public static function email_rfc($email)
|
||||
{
|
||||
$qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
|
||||
$dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
|
||||
$atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
|
||||
$pair = '\\x5c[\\x00-\\x7f]';
|
||||
|
||||
$domain_literal = "\\x5b($dtext|$pair)*\\x5d";
|
||||
$quoted_string = "\\x22($qtext|$pair)*\\x22";
|
||||
$sub_domain = "($atom|$domain_literal)";
|
||||
$word = "($atom|$quoted_string)";
|
||||
$domain = "$sub_domain(\\x2e$sub_domain)*";
|
||||
$local_part = "$word(\\x2e$word)*";
|
||||
$addr_spec = "$local_part\\x40$domain";
|
||||
|
||||
return (bool) preg_match('/^'.$addr_spec.'$/D', (string) $email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate URL
|
||||
*
|
||||
* @param string URL
|
||||
* @return boolean
|
||||
*/
|
||||
public static function url($url)
|
||||
{
|
||||
return (bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate IP
|
||||
*
|
||||
* @param string IP address
|
||||
* @param boolean allow IPv6 addresses
|
||||
* @param boolean allow private IP networks
|
||||
* @return boolean
|
||||
*/
|
||||
public static function ip($ip, $ipv6 = FALSE, $allow_private = TRUE)
|
||||
{
|
||||
// By default do not allow private and reserved range IPs
|
||||
$flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
||||
if ($allow_private === TRUE)
|
||||
$flags = FILTER_FLAG_NO_RES_RANGE;
|
||||
|
||||
if ($ipv6 === TRUE)
|
||||
return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flags);
|
||||
|
||||
return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flags | FILTER_FLAG_IPV4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a credit card number using the Luhn (mod10) formula.
|
||||
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
*
|
||||
* @param integer credit card number
|
||||
* @param string|array card type, or an array of card types
|
||||
* @return boolean
|
||||
*/
|
||||
public static function credit_card($number, $type = NULL)
|
||||
{
|
||||
// Remove all non-digit characters from the number
|
||||
if (($number = preg_replace('/\D+/', '', $number)) === '')
|
||||
return FALSE;
|
||||
|
||||
if ($type == NULL)
|
||||
{
|
||||
// Use the default type
|
||||
$type = 'default';
|
||||
}
|
||||
elseif (is_array($type))
|
||||
{
|
||||
foreach ($type as $t)
|
||||
{
|
||||
// Test each type for validity
|
||||
if (valid::credit_card($number, $t))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$cards = Kohana::config('credit_cards');
|
||||
|
||||
// Check card type
|
||||
$type = strtolower($type);
|
||||
|
||||
if ( ! isset($cards[$type]))
|
||||
return FALSE;
|
||||
|
||||
// Check card number length
|
||||
$length = strlen($number);
|
||||
|
||||
// Validate the card length by the card type
|
||||
if ( ! in_array($length, preg_split('/\D+/', $cards[$type]['length'])))
|
||||
return FALSE;
|
||||
|
||||
// Check card number prefix
|
||||
if ( ! preg_match('/^'.$cards[$type]['prefix'].'/', $number))
|
||||
return FALSE;
|
||||
|
||||
// No Luhn check required
|
||||
if ($cards[$type]['luhn'] == FALSE)
|
||||
return TRUE;
|
||||
|
||||
// Checksum of the card number
|
||||
$checksum = 0;
|
||||
|
||||
for ($i = $length - 1; $i >= 0; $i -= 2)
|
||||
{
|
||||
// Add up every 2nd digit, starting from the right
|
||||
$checksum += substr($number, $i, 1);
|
||||
}
|
||||
|
||||
for ($i = $length - 2; $i >= 0; $i -= 2)
|
||||
{
|
||||
// Add up every 2nd digit doubled, starting from the right
|
||||
$double = substr($number, $i, 1) * 2;
|
||||
|
||||
// Subtract 9 from the double where value is greater than 10
|
||||
$checksum += ($double >= 10) ? $double - 9 : $double;
|
||||
}
|
||||
|
||||
// If the checksum is a multiple of 10, the number is valid
|
||||
return ($checksum % 10 === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a phone number is valid.
|
||||
*
|
||||
* @param string phone number to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function phone($number, $lengths = NULL)
|
||||
{
|
||||
if ( ! is_array($lengths))
|
||||
{
|
||||
$lengths = array(7,10,11);
|
||||
}
|
||||
|
||||
// Remove all non-digit characters from the number
|
||||
$number = preg_replace('/\D+/', '', $number);
|
||||
|
||||
// Check if the number is within range
|
||||
return in_array(strlen($number), $lengths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a string is a valid date string.
|
||||
*
|
||||
* @param string date to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function date($str)
|
||||
{
|
||||
return (strtotime($str) !== FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a string consists of alphabetical characters only.
|
||||
*
|
||||
* @param string input string
|
||||
* @param boolean trigger UTF-8 compatibility
|
||||
* @return boolean
|
||||
*/
|
||||
public static function alpha($str, $utf8 = FALSE)
|
||||
{
|
||||
return ($utf8 === TRUE)
|
||||
? (bool) preg_match('/^\pL++$/uD', (string) $str)
|
||||
: ctype_alpha((string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a string consists of alphabetical characters and numbers only.
|
||||
*
|
||||
* @param string input string
|
||||
* @param boolean trigger UTF-8 compatibility
|
||||
* @return boolean
|
||||
*/
|
||||
public static function alpha_numeric($str, $utf8 = FALSE)
|
||||
{
|
||||
return ($utf8 === TRUE)
|
||||
? (bool) preg_match('/^[\pL\pN]++$/uD', (string) $str)
|
||||
: ctype_alnum((string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a string consists of alphabetical characters, numbers, underscores and dashes only.
|
||||
*
|
||||
* @param string input string
|
||||
* @param boolean trigger UTF-8 compatibility
|
||||
* @return boolean
|
||||
*/
|
||||
public static function alpha_dash($str, $utf8 = FALSE)
|
||||
{
|
||||
return ($utf8 === TRUE)
|
||||
? (bool) preg_match('/^[-\pL\pN_]++$/uD', (string) $str)
|
||||
: (bool) preg_match('/^[-a-z0-9_]++$/iD', (string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a string consists of digits only (no dots or dashes).
|
||||
*
|
||||
* @param string input string
|
||||
* @param boolean trigger UTF-8 compatibility
|
||||
* @return boolean
|
||||
*/
|
||||
public static function digit($str, $utf8 = FALSE)
|
||||
{
|
||||
return ($utf8 === TRUE)
|
||||
? (bool) preg_match('/^\pN++$/uD', (string) $str)
|
||||
: ctype_digit((string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a string is a valid number (negative and decimal numbers allowed).
|
||||
*
|
||||
* @see Uses locale conversion to allow decimal point to be locale specific.
|
||||
* @see http://www.php.net/manual/en/function.localeconv.php
|
||||
*
|
||||
* @param string input string
|
||||
* @return boolean
|
||||
*/
|
||||
public static function numeric($str)
|
||||
{
|
||||
// Use localeconv to set the decimal_point value: Usually a comma or period.
|
||||
$locale = localeconv();
|
||||
return (bool) preg_match('/^-?[0-9'.$locale['decimal_point'].']++$/D', (string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an integer is within a range.
|
||||
*
|
||||
* @param integer number to check
|
||||
* @param array valid range of input
|
||||
* @return boolean
|
||||
*/
|
||||
public static function range($number, array $range)
|
||||
{
|
||||
// Invalid by default
|
||||
$status = FALSE;
|
||||
|
||||
if (is_int($number) OR ctype_digit($number))
|
||||
{
|
||||
if (count($range) > 1)
|
||||
{
|
||||
if ($number >= $range[0] AND $number <= $range[1])
|
||||
{
|
||||
// Number is within the required range
|
||||
$status = TRUE;
|
||||
}
|
||||
}
|
||||
elseif ($number >= $range[0])
|
||||
{
|
||||
// Number is greater than the minimum
|
||||
$status = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string is a proper decimal format. The format array can be
|
||||
* used to specify a decimal length, or a number and decimal length, eg:
|
||||
* array(2) would force the number to have 2 decimal places, array(4,2)
|
||||
* would force the number to have 4 digits and 2 decimal places.
|
||||
*
|
||||
* @param string input string
|
||||
* @param array decimal format: y or x,y
|
||||
* @return boolean
|
||||
*/
|
||||
public static function decimal($str, $format = NULL)
|
||||
{
|
||||
// Create the pattern
|
||||
$pattern = '/^[0-9]%s\.[0-9]%s$/';
|
||||
|
||||
if ( ! empty($format))
|
||||
{
|
||||
if (count($format) > 1)
|
||||
{
|
||||
// Use the format for number and decimal length
|
||||
$pattern = sprintf($pattern, '{'.$format[0].'}', '{'.$format[1].'}');
|
||||
}
|
||||
elseif (count($format) > 0)
|
||||
{
|
||||
// Use the format as decimal length
|
||||
$pattern = sprintf($pattern, '+', '{'.$format[0].'}');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No format
|
||||
$pattern = sprintf($pattern, '+', '+');
|
||||
}
|
||||
|
||||
return (bool) preg_match($pattern, (string) $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string is a proper hexadecimal HTML color value. The validation
|
||||
* is quite flexible as it does not require an initial "#" and also allows for
|
||||
* the short notation using only three instead of six hexadecimal characters.
|
||||
* You may want to normalize these values with format::color().
|
||||
*
|
||||
* @param string input string
|
||||
* @return boolean
|
||||
*/
|
||||
public static function color($str)
|
||||
{
|
||||
return (bool) preg_match('/^#?+[0-9a-f]{3}(?:[0-9a-f]{3})?$/iD', $str);
|
||||
}
|
||||
|
||||
} // End valid
|
250
web_client/system/libraries/Cache.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Provides a driver-based interface for finding, creating, and deleting cached
|
||||
* resources. Caches are identified by a unique string. Tagging of caches is
|
||||
* also supported, and caches can be found and deleted by id or tag.
|
||||
*
|
||||
* $Id: Cache.php 4605 2009-09-14 17:22:21Z kiall $
|
||||
*
|
||||
* @package Cache
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Cache_Core {
|
||||
|
||||
protected static $instances = array();
|
||||
|
||||
// Configuration
|
||||
protected $config;
|
||||
|
||||
// Driver object
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Returns a singleton instance of Cache.
|
||||
*
|
||||
* @param string configuration
|
||||
* @return Cache_Core
|
||||
*/
|
||||
public static function & instance($config = FALSE)
|
||||
{
|
||||
if ( ! isset(Cache::$instances[$config]))
|
||||
{
|
||||
// Create a new instance
|
||||
Cache::$instances[$config] = new Cache($config);
|
||||
}
|
||||
|
||||
return Cache::$instances[$config];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configured driver and validates it.
|
||||
*
|
||||
* @param array|string custom configuration or config group name
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($config = FALSE)
|
||||
{
|
||||
if (is_string($config))
|
||||
{
|
||||
$name = $config;
|
||||
|
||||
// Test the config group name
|
||||
if (($config = Kohana::config('cache.'.$config)) === NULL)
|
||||
throw new Cache_Exception('The :group: group is not defined in your configuration.', array(':group:' => $name));
|
||||
}
|
||||
|
||||
if (is_array($config))
|
||||
{
|
||||
// Append the default configuration options
|
||||
$config += Kohana::config('cache.default');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load the default group
|
||||
$config = Kohana::config('cache.default');
|
||||
}
|
||||
|
||||
// Cache the config in the object
|
||||
$this->config = $config;
|
||||
|
||||
// Set driver name
|
||||
$driver = 'Cache_'.ucfirst($this->config['driver']).'_Driver';
|
||||
|
||||
// Load the driver
|
||||
if ( ! Kohana::auto_load($driver))
|
||||
throw new Cache_Exception('The :driver: driver for the :class: library could not be found',
|
||||
array(':driver:' => $this->config['driver'], ':class:' => get_class($this)));
|
||||
|
||||
// Initialize the driver
|
||||
$this->driver = new $driver($this->config['params']);
|
||||
|
||||
// Validate the driver
|
||||
if ( ! ($this->driver instanceof Cache_Driver))
|
||||
throw new Cache_Exception('The :driver: driver for the :library: library must implement the :interface: interface',
|
||||
array(':driver:' => $this->config['driver'], ':library:' => get_class($this), ':interface:' => 'Cache_Driver'));
|
||||
|
||||
Kohana_Log::add('debug', 'Cache Library initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache items
|
||||
*/
|
||||
public function set($key, $value = NULL, $tags = NULL, $lifetime = NULL)
|
||||
{
|
||||
if ($lifetime === NULL)
|
||||
{
|
||||
$lifetime = $this->config['lifetime'];
|
||||
}
|
||||
|
||||
if ( ! is_array($key))
|
||||
{
|
||||
$key = array($key => $value);
|
||||
}
|
||||
|
||||
if ($this->config['prefix'] !== NULL)
|
||||
{
|
||||
$key = $this->add_prefix($key);
|
||||
|
||||
if ($tags !== NULL)
|
||||
{
|
||||
$tags = $this->add_prefix($tags, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->driver->set($key, $tags, $lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cache items by key
|
||||
*/
|
||||
public function get($keys)
|
||||
{
|
||||
$single = FALSE;
|
||||
|
||||
if ( ! is_array($keys))
|
||||
{
|
||||
$keys = array($keys);
|
||||
$single = TRUE;
|
||||
}
|
||||
|
||||
if ($this->config['prefix'] !== NULL)
|
||||
{
|
||||
$keys = $this->add_prefix($keys, FALSE);
|
||||
|
||||
if ( ! $single)
|
||||
{
|
||||
return $this->strip_prefix($this->driver->get($keys, $single));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->driver->get($keys, $single);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache items by tags
|
||||
*/
|
||||
public function get_tag($tags)
|
||||
{
|
||||
if ( ! is_array($tags))
|
||||
{
|
||||
$tags = array($tags);
|
||||
}
|
||||
|
||||
if ($this->config['prefix'] !== NULL)
|
||||
{
|
||||
$tags = $this->add_prefix($tags, FALSE);
|
||||
return $this->strip_prefix($this->driver->get_tag($tags));
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->driver->get_tag($tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache item by key
|
||||
*/
|
||||
public function delete($keys)
|
||||
{
|
||||
if ( ! is_array($keys))
|
||||
{
|
||||
$keys = array($keys);
|
||||
}
|
||||
|
||||
if ($this->config['prefix'] !== NULL)
|
||||
{
|
||||
$keys = $this->add_prefix($keys, FALSE);
|
||||
}
|
||||
|
||||
return $this->driver->delete($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cache items by tag
|
||||
*/
|
||||
public function delete_tag($tags)
|
||||
{
|
||||
if ( ! is_array($tags))
|
||||
{
|
||||
$tags = array($tags);
|
||||
}
|
||||
|
||||
if ($this->config['prefix'] !== NULL)
|
||||
{
|
||||
$tags = $this->add_prefix($tags, FALSE);
|
||||
}
|
||||
|
||||
return $this->driver->delete_tag($tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the cache
|
||||
*/
|
||||
public function delete_all()
|
||||
{
|
||||
return $this->driver->delete_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a prefix to keys or tags
|
||||
*/
|
||||
protected function add_prefix($array, $to_key = TRUE)
|
||||
{
|
||||
$out = array();
|
||||
|
||||
foreach($array as $key => $value)
|
||||
{
|
||||
if ($to_key)
|
||||
{
|
||||
$out[$this->config['prefix'].$key] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$out[$key] = $this->config['prefix'].$value;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip a prefix to keys or tags
|
||||
*/
|
||||
protected function strip_prefix($array)
|
||||
{
|
||||
$out = array();
|
||||
|
||||
$start = strlen($this->config['prefix']);
|
||||
|
||||
foreach($array as $key => $value)
|
||||
{
|
||||
$out[substr($key, $start)] = $value;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
} // End Cache Library
|
12
web_client/system/libraries/Cache_Exception.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* $Id: Kohana_User_Exception.php 4543 2009-09-04 16:58:56Z nodren $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
|
||||
class Cache_Exception_Core extends Kohana_Exception {}
|
||||
// End Kohana User Exception
|
51
web_client/system/libraries/Controller.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* Kohana Controller class. The controller class must be extended to work
|
||||
* properly, so this class is defined as abstract.
|
||||
*
|
||||
* $Id: Controller.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Core
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Controller_Core {
|
||||
|
||||
// Allow all controllers to run in production by default
|
||||
const ALLOW_PRODUCTION = TRUE;
|
||||
|
||||
/**
|
||||
* Loads URI, and Input into this controller.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (Kohana::$instance == NULL)
|
||||
{
|
||||
// Set the instance to the first controller loaded
|
||||
Kohana::$instance = $this;
|
||||
}
|
||||
|
||||
// URI should always be available
|
||||
$this->uri = URI::instance();
|
||||
|
||||
// Input should always be available
|
||||
$this->input = Input::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles methods that do not exist.
|
||||
*
|
||||
* @param string method name
|
||||
* @param array arguments
|
||||
* @return void
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// Default to showing a 404 page
|
||||
Event::run('system.404');
|
||||
}
|
||||
|
||||
} // End Controller Class
|
645
web_client/system/libraries/Database.php
Normal file
@ -0,0 +1,645 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Database wrapper.
|
||||
*
|
||||
* $Id: Database.php 4709 2009-12-10 05:09:35Z isaiah $
|
||||
*
|
||||
* @package Kohana
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Database_Core {
|
||||
|
||||
const SELECT = 1;
|
||||
const INSERT = 2;
|
||||
const UPDATE = 3;
|
||||
const DELETE = 4;
|
||||
const CROSS_REQUEST = 5;
|
||||
const PER_REQUEST = 6;
|
||||
|
||||
protected static $instances = array();
|
||||
|
||||
// Global benchmarks
|
||||
public static $benchmarks = array();
|
||||
|
||||
// Last execute query
|
||||
protected $last_query;
|
||||
|
||||
// Configuration array
|
||||
protected $config;
|
||||
|
||||
// Required configuration keys
|
||||
protected $config_required = array();
|
||||
|
||||
// Raw server connection
|
||||
protected $connection;
|
||||
|
||||
// Cache (Cache object for cross-request, array for per-request)
|
||||
protected $cache;
|
||||
|
||||
// Quote character to use for identifiers (tables/columns/aliases)
|
||||
protected $quote = '"';
|
||||
|
||||
/**
|
||||
* Returns a singleton instance of Database.
|
||||
*
|
||||
* @param string Database name
|
||||
* @return Database_Core
|
||||
*/
|
||||
public static function instance($name = 'default')
|
||||
{
|
||||
if ( ! isset(Database::$instances[$name]))
|
||||
{
|
||||
// Load the configuration for this database group
|
||||
$config = Kohana::config('database.'.$name);
|
||||
|
||||
if (is_string($config['connection']))
|
||||
{
|
||||
// Parse the DSN into connection array
|
||||
$config['connection'] = Database::parse_dsn($config['connection']);
|
||||
}
|
||||
|
||||
// Set the driver class name
|
||||
$driver = 'Database_'.ucfirst($config['connection']['type']);
|
||||
|
||||
// Create the database connection instance
|
||||
Database::$instances[$name] = new $driver($config);
|
||||
}
|
||||
|
||||
return Database::$instances[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Database object
|
||||
*
|
||||
* @param array Database config array
|
||||
* @return Database_Core
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
// Store the config locally
|
||||
$this->config = $config;
|
||||
|
||||
if ($this->config['cache'] !== FALSE)
|
||||
{
|
||||
if (is_string($this->config['cache']))
|
||||
{
|
||||
// Use Cache library
|
||||
$this->cache = new Cache($this->config['cache']);
|
||||
}
|
||||
elseif ($this->config['cache'] === TRUE)
|
||||
{
|
||||
// Use array
|
||||
$this->cache = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function connect();
|
||||
|
||||
/**
|
||||
* Disconnects from the database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function disconnect();
|
||||
|
||||
/**
|
||||
* Sets the character set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function set_charset($charset);
|
||||
|
||||
/**
|
||||
* Executes the query
|
||||
*
|
||||
* @param string SQL
|
||||
* @return Database_Result
|
||||
*/
|
||||
abstract public function query_execute($sql);
|
||||
|
||||
/**
|
||||
* Escapes the given value
|
||||
*
|
||||
* @param mixed Value
|
||||
* @return mixed Escaped value
|
||||
*/
|
||||
abstract public function escape($value);
|
||||
|
||||
/**
|
||||
* List constraints for the given table
|
||||
*
|
||||
* @param string Table name
|
||||
* @return array
|
||||
*/
|
||||
abstract public function list_constraints($table);
|
||||
|
||||
/**
|
||||
* List fields for the given table
|
||||
*
|
||||
* @param string Table name
|
||||
* @return array
|
||||
*/
|
||||
abstract public function list_fields($table);
|
||||
|
||||
/**
|
||||
* List tables for the given connection (checks for prefix)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function list_tables();
|
||||
|
||||
/**
|
||||
* Converts the given DSN string to an array of database connection components
|
||||
*
|
||||
* @param string DSN string
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_dsn($dsn)
|
||||
{
|
||||
$db = array
|
||||
(
|
||||
'type' => FALSE,
|
||||
'user' => FALSE,
|
||||
'pass' => FALSE,
|
||||
'host' => FALSE,
|
||||
'port' => FALSE,
|
||||
'socket' => FALSE,
|
||||
'database' => FALSE
|
||||
);
|
||||
|
||||
// Get the protocol and arguments
|
||||
list ($db['type'], $connection) = explode('://', $dsn, 2);
|
||||
|
||||
if ($connection[0] === '/')
|
||||
{
|
||||
// Strip leading slash
|
||||
$db['database'] = substr($connection, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$connection = parse_url('http://'.$connection);
|
||||
|
||||
if (isset($connection['user']))
|
||||
{
|
||||
$db['user'] = $connection['user'];
|
||||
}
|
||||
|
||||
if (isset($connection['pass']))
|
||||
{
|
||||
$db['pass'] = $connection['pass'];
|
||||
}
|
||||
|
||||
if (isset($connection['port']))
|
||||
{
|
||||
$db['port'] = $connection['port'];
|
||||
}
|
||||
|
||||
if (isset($connection['host']))
|
||||
{
|
||||
if ($connection['host'] === 'unix(')
|
||||
{
|
||||
list($db['socket'], $connection['path']) = explode(')', $connection['path'], 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db['host'] = $connection['host'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($connection['path']) AND $connection['path'])
|
||||
{
|
||||
// Strip leading slash
|
||||
$db['database'] = substr($connection['path'], 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last executed query for this database
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function last_query()
|
||||
{
|
||||
return $this->last_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given query, returning the cached version if enabled
|
||||
*
|
||||
* @param string SQL query
|
||||
* @return Database_Result
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
// Start the benchmark
|
||||
$start = microtime(TRUE);
|
||||
|
||||
if (is_array($this->cache))
|
||||
{
|
||||
$hash = $this->query_hash($sql);
|
||||
|
||||
if (isset($this->cache[$hash]))
|
||||
{
|
||||
// Use cached result
|
||||
$result = $this->cache[$hash];
|
||||
|
||||
// It's from cache
|
||||
$sql .= ' [CACHE]';
|
||||
}
|
||||
else
|
||||
{
|
||||
// No cache, execute query and store in cache
|
||||
$result = $this->cache[$hash] = $this->query_execute($sql);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Execute the query, cache is off
|
||||
$result = $this->query_execute($sql);
|
||||
}
|
||||
|
||||
// Stop the benchmark
|
||||
$stop = microtime(TRUE);
|
||||
|
||||
if ($this->config['benchmark'] === TRUE)
|
||||
{
|
||||
// Benchmark the query
|
||||
Database::$benchmarks[] = array('query' => $sql, 'time' => $stop - $start, 'rows' => count($result));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the query on the cache (and caches it if it's not found)
|
||||
*
|
||||
* @param string query
|
||||
* @param int time-to-live (NULL for Cache default)
|
||||
* @return Database_Cache_Result
|
||||
*/
|
||||
public function query_cache($sql, $ttl)
|
||||
{
|
||||
if ( ! $this->cache instanceof Cache)
|
||||
{
|
||||
throw new Database_Exception('Database :name has not been configured to use the Cache library.');
|
||||
}
|
||||
|
||||
// Start the benchmark
|
||||
$start = microtime(TRUE);
|
||||
|
||||
$hash = $this->query_hash($sql);
|
||||
|
||||
if (($data = $this->cache->get($hash)) !== NULL)
|
||||
{
|
||||
// Found in cache, create result
|
||||
$result = new Database_Cache_Result($data, $sql, $this->config['object']);
|
||||
|
||||
// It's from the cache
|
||||
$sql .= ' [CACHE]';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Run the query and return the full array of rows
|
||||
$data = $this->query_execute($sql)->as_array(TRUE);
|
||||
|
||||
// Set the Cache
|
||||
$this->cache->set($hash, $data, NULL, $ttl);
|
||||
|
||||
// Create result
|
||||
$result = new Database_Cache_Result($data, $sql, $this->config['object']);
|
||||
}
|
||||
|
||||
// Stop the benchmark
|
||||
$stop = microtime(TRUE);
|
||||
|
||||
if ($this->config['benchmark'] === TRUE)
|
||||
{
|
||||
// Benchmark the query
|
||||
Database::$benchmarks[] = array('query' => $sql, 'time' => $stop - $start, 'rows' => count($result));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a hash for the given query
|
||||
*
|
||||
* @param string SQL query string
|
||||
* @return string
|
||||
*/
|
||||
protected function query_hash($sql)
|
||||
{
|
||||
return sha1(str_replace("\n", ' ', trim($sql)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the internal query cache.
|
||||
*
|
||||
* @param mixed clear cache by SQL statement, NULL for all, or TRUE for last query
|
||||
* @param integer Type of cache to clear, Database::CROSS_REQUEST or Database::PER_REQUEST
|
||||
* @return Database
|
||||
*/
|
||||
public function clear_cache($sql = NULL, $type = NULL)
|
||||
{
|
||||
if ($this->cache instanceof Cache AND ($type == NULL OR $type == Database::CROSS_REQUEST))
|
||||
{
|
||||
// Using cross-request Cache library
|
||||
if ($sql === TRUE)
|
||||
{
|
||||
$this->cache->delete($this->query_hash($this->last_query));
|
||||
}
|
||||
elseif (is_string($sql))
|
||||
{
|
||||
$this->cache->delete($this->query_hash($sql));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->cache->delete_all();
|
||||
}
|
||||
}
|
||||
elseif (is_array($this->cache) AND ($type == NULL OR $type == Database::PER_REQUEST))
|
||||
{
|
||||
// Using per-request memory cache
|
||||
if ($sql === TRUE)
|
||||
{
|
||||
unset($this->cache[$this->query_hash($this->last_query)]);
|
||||
}
|
||||
elseif (is_string($sql))
|
||||
{
|
||||
unset($this->cache[$this->query_hash($sql)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->cache = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes the given value
|
||||
*
|
||||
* @param mixed value
|
||||
* @return mixed
|
||||
*/
|
||||
public function quote($value)
|
||||
{
|
||||
if ( ! $this->config['escape'])
|
||||
return $value;
|
||||
|
||||
if ($value === NULL)
|
||||
{
|
||||
return 'NULL';
|
||||
}
|
||||
elseif ($value === TRUE)
|
||||
{
|
||||
return 'TRUE';
|
||||
}
|
||||
elseif ($value === FALSE)
|
||||
{
|
||||
return 'FALSE';
|
||||
}
|
||||
elseif (is_int($value))
|
||||
{
|
||||
return (int) $value;
|
||||
}
|
||||
elseif ($value instanceof Database_Expression)
|
||||
{
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
return '\''.$this->escape($value).'\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a table, adding the table prefix
|
||||
* Reserved characters not allowed in table names for the builder are [ .*] (space, dot, asterisk)
|
||||
*
|
||||
* @param string|array table name or array - 'users u' or array('u' => 'users') both valid
|
||||
* @param string table alias
|
||||
* @return string
|
||||
*/
|
||||
public function quote_table($table, $alias = NULL)
|
||||
{
|
||||
if (is_array($table))
|
||||
{
|
||||
// Using array('u' => 'user')
|
||||
list($alias, $table) = each($table);
|
||||
}
|
||||
elseif (strpos(' ', $table) !== FALSE)
|
||||
{
|
||||
// Using format 'user u'
|
||||
list($table, $alias) = explode(' ', $table);
|
||||
}
|
||||
|
||||
if ($table instanceof Database_Expression)
|
||||
{
|
||||
if ($alias)
|
||||
{
|
||||
if ($this->config['escape'])
|
||||
{
|
||||
$alias = $this->quote.$alias.$this->quote;
|
||||
}
|
||||
|
||||
return $table.' AS '.$alias;
|
||||
}
|
||||
|
||||
return (string) $table;
|
||||
}
|
||||
|
||||
if ($this->config['table_prefix'])
|
||||
{
|
||||
$table = $this->config['table_prefix'].$table;
|
||||
}
|
||||
|
||||
if ($alias)
|
||||
{
|
||||
if ($this->config['escape'])
|
||||
{
|
||||
$table = $this->quote.$table.$this->quote;
|
||||
$alias = $this->quote.$alias.$this->quote;
|
||||
}
|
||||
|
||||
return $table.' AS '.$alias;
|
||||
}
|
||||
|
||||
if ($this->config['escape'])
|
||||
{
|
||||
$table = $this->quote.$table.$this->quote;
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes column or table.column, adding the table prefix if necessary
|
||||
* Reserved characters not allowed in table names for the builder are [ .*] (space, dot, asterisk)
|
||||
* Complex column names must have table/columns in double quotes, e.g. array('mycount' => 'COUNT("users.id")')
|
||||
*
|
||||
* @param string|array column name or array('u' => 'COUNT("*")')
|
||||
* @param string column alias
|
||||
* @return string
|
||||
*/
|
||||
public function quote_column($column, $alias = NULL)
|
||||
{
|
||||
if ($column === '*')
|
||||
return $column;
|
||||
|
||||
if (is_array($column))
|
||||
{
|
||||
list($alias, $column) = each($column);
|
||||
}
|
||||
|
||||
if ($column instanceof Database_Expression)
|
||||
{
|
||||
if ($alias)
|
||||
{
|
||||
if ($this->config['escape'])
|
||||
{
|
||||
$alias = $this->quote.$alias.$this->quote;
|
||||
}
|
||||
|
||||
return $column.' AS '.$alias;
|
||||
}
|
||||
|
||||
return (string) $column;
|
||||
}
|
||||
|
||||
if ($this->config['table_prefix'] AND strpos($column, '.') !== FALSE)
|
||||
{
|
||||
if (strpos($column, '"') !== FALSE)
|
||||
{
|
||||
// Find "table.column" and replace them with "[prefix]table.column"
|
||||
$column = preg_replace('/"([^.]++)\.([^"]++)"/', '"'.$this->config['table_prefix'].'$1.$2"', $column);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Attach table prefix if table.column format
|
||||
$column = $this->config['table_prefix'].$column;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->config['escape'])
|
||||
{
|
||||
if (strpos($column, '"') === FALSE)
|
||||
{
|
||||
// Quote the column
|
||||
$column = $this->quote.$column.$this->quote;
|
||||
}
|
||||
elseif ($this->quote !== '"')
|
||||
{
|
||||
// Replace double quotes
|
||||
$column = str_replace('"', $this->quote, $column);
|
||||
}
|
||||
|
||||
// Replace . with "."
|
||||
$column = str_replace('.', $this->quote.'.'.$this->quote, $column);
|
||||
|
||||
// Unescape any asterisks
|
||||
$column = str_replace($this->quote.'*'.$this->quote, '*', $column);
|
||||
|
||||
if ($alias)
|
||||
{
|
||||
// Quote the alias
|
||||
return $column.' AS '.$this->quote.$alias.$this->quote;
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
// Strip double quotes
|
||||
$column = str_replace('"', '', $column);
|
||||
|
||||
if ($alias)
|
||||
return $column.' AS '.$alias;
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table prefix
|
||||
*
|
||||
* @param string Optional new table prefix to set
|
||||
* @return string
|
||||
*/
|
||||
public function table_prefix($new_prefix = NULL)
|
||||
{
|
||||
$prefix = $this->config['table_prefix'];
|
||||
|
||||
if ($new_prefix !== NULL)
|
||||
{
|
||||
// Set a new prefix
|
||||
$this->config['table_prefix'] = $new_prefix;
|
||||
}
|
||||
|
||||
return $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches SQL type information about a field, in a generic format.
|
||||
*
|
||||
* @param string field datatype
|
||||
* @return array
|
||||
*/
|
||||
protected function sql_type($str)
|
||||
{
|
||||
static $sql_types;
|
||||
|
||||
if ($sql_types === NULL)
|
||||
{
|
||||
// Load SQL data types
|
||||
$sql_types = Kohana::config('sql_types');
|
||||
}
|
||||
|
||||
$str = trim($str);
|
||||
|
||||
if (($open = strpos($str, '(')) !== FALSE)
|
||||
{
|
||||
// Closing bracket
|
||||
$close = strpos($str, ')', $open);
|
||||
|
||||
// Length without brackets
|
||||
$length = substr($str, $open + 1, $close - 1 - $open);
|
||||
|
||||
// Type without the length
|
||||
$type = substr($str, 0, $open).substr($str, $close + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No length
|
||||
$type = $str;
|
||||
}
|
||||
|
||||
if (empty($sql_types[$type]))
|
||||
throw new Database_Exception('Undefined field type :type', array(':type' => $str));
|
||||
|
||||
// Fetch the field definition
|
||||
$field = $sql_types[$type];
|
||||
|
||||
$field['sql_type'] = $type;
|
||||
|
||||
if (isset($length))
|
||||
{
|
||||
// Add the length to the field info
|
||||
$field['length'] = $length;
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
} // End Database
|
1005
web_client/system/libraries/Database_Builder.php
Normal file
83
web_client/system/libraries/Database_Cache_Result.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Cached database result.
|
||||
*
|
||||
* $Id: Database_Cache_Result.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Kohana
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Database_Cache_Result_Core extends Database_Result {
|
||||
|
||||
/**
|
||||
* Result data (array of rows)
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
public function __construct($data, $sql, $return_objects)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->sql = $sql;
|
||||
$this->total_rows = count($data);
|
||||
$this->return_objects = $return_objects;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
public function as_array($return = FALSE)
|
||||
{
|
||||
// Return arrays rather than objects
|
||||
$this->return_objects = FALSE;
|
||||
|
||||
if ( ! $return )
|
||||
{
|
||||
// Return this result object
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Return the entire array of rows
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function as_object($class = NULL, $return = FALSE)
|
||||
{
|
||||
if ($class !== NULL)
|
||||
throw new Database_Exception('Database cache results do not support object casting');
|
||||
|
||||
// Return objects of type $class (or stdClass if none given)
|
||||
$this->return_objects = TRUE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function seek($offset)
|
||||
{
|
||||
if ( ! $this->offsetExists($offset))
|
||||
return FALSE;
|
||||
|
||||
$this->current_row = $offset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
if ($this->return_objects)
|
||||
{
|
||||
// Return a new object with the current row of data
|
||||
return (object) $this->data[$this->current_row];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return an array of the row
|
||||
return $this->data[$this->current_row];
|
||||
}
|
||||
}
|
||||
|
||||
} // End Database_Cache_Result
|
17
web_client/system/libraries/Database_Exception.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Database exceptions.
|
||||
*
|
||||
* $Id: Database_Exception.php 4679 2009-11-10 01:45:52Z isaiah $
|
||||
*
|
||||
* @package Kohana
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Database_Exception_Core extends Kohana_Exception {
|
||||
|
||||
// Database error code
|
||||
protected $code = E_DATABASE_ERROR;
|
||||
|
||||
} // End Database_Exception
|