Moved some more common code into lnapp

This commit is contained in:
Deon George 2014-02-17 11:29:11 +11:00
parent 7a78a9a7d6
commit b2912e4007
11 changed files with 190 additions and 6 deletions

View File

@ -0,0 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
abstract class Controller_TemplateDefault extends lnApp_Controller_TemplateDefault {}
?>

4
classes/Request.php Normal file
View File

@ -0,0 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
class Request extends lnApp_Request {}
?>

View File

@ -35,6 +35,9 @@ abstract class lnApp_Controller_TemplateDefault extends Kohana_Controller_Templa
*/ */
protected $secure_actions = array(); protected $secure_actions = array();
// Our acccount object
protected $ao;
public function __construct(Request $request, Response $response) { public function __construct(Request $request, Response $response) {
if (Config::theme()) if (Config::theme())
$this->template = Config::theme().'/page'; $this->template = Config::theme().'/page';
@ -69,6 +72,16 @@ abstract class lnApp_Controller_TemplateDefault extends Kohana_Controller_Templa
* @uses meta * @uses meta
*/ */
public function before() { public function before() {
if ($this->auth_required) {
if (! count($this->secure_actions) OR (! isset($this->secure_actions[Request::current()->action()])))
throw HTTP_Exception::factory(403,'Class has no security defined :class, or no security configured for :method',array(':class'=>get_class($this),':method'=>Request::current()->action()));
$this->ao = Auth::instance()->get_user();
if (! is_null($this->ao) AND (is_string($this->ao) OR ! $this->ao->loaded()))
throw HTTP_Exception::factory(501,'Account doesnt exist :account ?',array(':account'=>(is_string($this->ao) OR is_null($this->ao)) ? $this->ao : Auth::instance()->get_user()->id));
}
// Actions that start with ajax, should only be ajax // Actions that start with ajax, should only be ajax
if (! Kohana::$config->load('debug')->ajax AND preg_match('/^ajax/',Request::current()->action()) AND ! Request::current()->is_ajax()) if (! Kohana::$config->load('debug')->ajax AND preg_match('/^ajax/',Request::current()->action()) AND ! Request::current()->is_ajax())
throw HTTP_Exception::factory(412,_('Unable to fulfil request.')); throw HTTP_Exception::factory(412,_('Unable to fulfil request.'));

View File

@ -76,6 +76,56 @@ abstract class lnApp_ORM extends Kohana_ORM {
return $result; return $result;
} }
/**
* This function is our AJAX helper, used by module list_autocomplete()
*/
public function list_autocomplete($term,$index,$value,array $label,array $limit=array(),array $options=NULL) {
$result = array();
$query = empty($options['object']) ? $this : $options['object'];
foreach ($limit as $w) {
list($k,$s,$v) = $w;
$query->and_where($k,$s,$v);
}
$c = 0;
foreach ((empty($options['object']) ? $query->find_all() : $query->execute()) as $o) {
// If we got here via a DB query, we need to reload our ORM object from the result.
if (! is_object($o)) {
if (empty($options['key']))
throw new Kohana_Exception('Missing key for non object');
$o = $this->clear()->where($options['key'],'=',$o[$options['key']])->find();
}
switch ($index) {
case 'url':
if (empty($options['urlprefix']))
throw new Kohana_Exception('Missing URL Prefix');
$v = $options['urlprefix'].$o->resolve($value);
break;
default: $v = $o->resolve($value);
}
$k = '';
foreach ($label as $k => $details)
foreach ($details as $lvalue)
$k = preg_replace('/%s/',$o->resolve($lvalue),$k,1);
$result[$c++] = array(
'value'=>$v,
'label'=>$k,
);
}
return $result;
}
/** /**
* Return an array of data that can be used in a SELECT statement. * Return an array of data that can be used in a SELECT statement.
* The ID and VALUE is defined in the model for the select. * The ID and VALUE is defined in the model for the select.
@ -84,7 +134,7 @@ abstract class lnApp_ORM extends Kohana_ORM {
$result = array(); $result = array();
if ($blank) if ($blank)
$result[] = ''; $result[NULL] = '';
if ($this->_form AND array_intersect(array('id','value'),$this->_form)) if ($this->_form AND array_intersect(array('id','value'),$this->_form))
foreach ($this->find_all() as $o) foreach ($this->find_all() as $o)

31
classes/lnApp/Request.php Normal file
View File

@ -0,0 +1,31 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* Request. Uses the [Route] class to determine what
* [Controller] to send the request to.
*
* @package lnApp
* @category Modifications
* @author Deon George
* @copyright (c) 2009-2013 Deon George
* @license http://dev.leenooks.net/license.html
*/
abstract class lnApp_Request extends Kohana_Request {
/**
* Sets and gets the directory for the controller.
*
* We override the Kohana version, so that we can have short directory URLs.
* eg: admin=>a,reseller=>r.
*
* @param string $directory Directory to execute the controller from
* @return mixed
*/
public function directory($directory = NULL) {
// If $directory is NULL, we are a getter and see if we need to expand the directory
if ($directory === NULL AND $this->_directory)
$this->_directory = URL::dir($this->_directory);
return parent::directory($directory);
}
}
?>

View File

@ -63,7 +63,11 @@ abstract class lnApp_Table {
$x = $d; $x = $d;
else else
$x = $d->display($key); $x = isset($d->{$key}) ? $d->display($key) : '';
// We cant display array values
if (is_array($x))
$x = array_shift($x);
if (isset($this->prepend[$key]) AND $x) { if (isset($this->prepend[$key]) AND $x) {
foreach ($this->prepend[$key] as $act => $data) { foreach ($this->prepend[$key] as $act => $data) {

View File

@ -9,7 +9,7 @@
* @copyright (c) 2014 Deon George * @copyright (c) 2014 Deon George
* @license http://dev.leenooks.net/license.html * @license http://dev.leenooks.net/license.html
*/ */
class lnApp_URL extends Kohana_URL { abstract class lnApp_URL extends Kohana_URL {
// Our method paths for different functions // Our method paths for different functions
public static $method_directory = array( public static $method_directory = array(
'admin'=>'a', 'admin'=>'a',

BIN
media/img/spinner.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

53
media/js/search.js Normal file
View File

@ -0,0 +1,53 @@
$(document).ready(function() {
$("input[name=search-query]").typeahead({
minLength: 2,
source: function (query,process) {
if(query.length==0) return false;
search('u/search/ajaxlist',query,process);
},
matcher: function () { return true; },
updater: function (item) {
window.parent.location.href = site_url+users[item];
},
});
});
var c=0;
var search = _.debounce(function(url,query,process){
$.ajax({
url : site_url+url,
type : 'GET',
data : 'term=' + query,
dataType : 'JSON',
async : true,
cache : false,
beforeSend : function() {
if (c++ == 0)
$('img[name=searching]').css('visibility', 'visible');
},
success : function(data) {
// if json is null, means no match, won't do again.
if(data==null || (data.length===0)) return;
users = {};
userLabels = [];
_.each(data,function(item,ix,list) {
if (_.contains(users,item.label))
item.label = item.label + ' #' + item.value;
userLabels.push(item.label);
users[item.label] = item.value;
});
process(userLabels);
},
complete : function() {
if (--c == 0)
$('img[name=searching]').css('visibility', 'hidden');
}
})
}, 500);

View File

@ -67,3 +67,24 @@ table .text-right {
content: ""; content: "";
clear: both; clear: both;
} }
.navbar .navbar-search .left-inner-addon {
position: relative;
}
.navbar .navbar-search .navbar-search-addon input.search-query {
padding-left: 30px;
padding-right: 30px;
width: 150px;
}
.navbar .navbar-search .navbar-search-addon i {
position: absolute;
padding: 8px 10px;
pointer-events: none;
}
.navbar .navbar-search .navbar-search-addon img {
position: absolute;
padding: 6px 10px;
pointer-events: none;
right: 0px;
visibility: hidden;
}

View File

@ -46,9 +46,13 @@
<?php echo $navbar; ?> <?php echo $navbar; ?>
</ul> </ul>
<form class="navbar-search pull-right"> <div class="navbar-search pull-right">
<div class="navbar-search-addon">
<i class="icon-search"></i>
<?php echo HTML::image('media/img/spinner.gif',array('class'=>'right','name'=>'searching')); ?>
<input type="text" name="search-query" class="search-query" placeholder="Search" data-provide="typeahead"> <input type="text" name="search-query" class="search-query" placeholder="Search" data-provide="typeahead">
</form> </div>
</div>
</div><!--/.nav-collapse --> </div><!--/.nav-collapse -->
</div> <!-- /container --> </div> <!-- /container -->