Skip to content

Commit

Permalink
Content manager update for large databases
Browse files Browse the repository at this point in the history
  • Loading branch information
Laca committed May 18, 2016
1 parent 96a0208 commit 1245fb3
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 22 deletions.
63 changes: 46 additions & 17 deletions assets/js/asset.form.js
Expand Up @@ -397,23 +397,52 @@ MMWizard.prototype = new MFrm();
$(document).ready(function () {
$(".leaflet-routing-container").hide();

/* var picker_start = new Pikaday({
field: document.getElementById('content_start'),
showWeekNumber: true,
firstDay: 1,
format: 'YYYY-MM-DD',
showMonthAfterYear: true,
yearRange: [1900,2030]
});
var picker_end = new Pikaday({
field: document.getElementById('content_end'),
showWeekNumber: true,
firstDay: 1,
format: 'YYYY-MM-DD',
showMonthAfterYear: true,
yearRange: [1900,2030]
}); */
//$("#content_table_search").click(function (event) {
$("#contentlist_form").submit(function(event) {

if (!$('#inputAddress').val()) return null;
var module = 'majax';

$.ajaxSetup({async: false});

var url = 'index.php?module=' + module + '&task=geocode';
url += '&address=' + $('#inputAddress').val();
url += '&mapi_csrf=' + encodeURIComponent($('#mapi_csrf').val());

if ('#content_table_search') $('#content_table_search').html('Searching address...');

$.ajax({
url: url,
dataType: "json"
}).done(function(result) {
if (result.status === 'OK') {
if ($('#content_listfilter_lat')) $('#content_listfilter_lat').val(result.lat);
if ($('#content_listfilter_lon')) $('#content_listfilter_lon').val(result.lng);
//map.panTo( [result.lat, result.lng] );
//marker.setLatLng( [result.lat, result.lng] );
} else {
alert('Address not found!');
if ($('#inputAddress')) $('#inputAddress').val('');
return false;
}
}).done( function() {
if ('#content_table_search') $('#content_table_search').html('Processing Query...');
});

//alert(url);
//return false;
});

$("#inputAddress").autocomplete("./../manager/modules/mcontent/ajax/GetAddressList.php", {
width: 300,
matchContains: true,
mustMatch: false,
//minChars: 3,
//multiple: true,
//highlight: false,
//multipleSeparator: ",",
selectFirst: false
});

$("#address").autocomplete("./../modules/event/ajax/GetAddressList.php", {
width: 300,
Expand Down
136 changes: 136 additions & 0 deletions includes/listings.php
Expand Up @@ -3,6 +3,142 @@
// no direct access to this file
defined( 'DACCESS' ) or die;

function mapi_list_filtered($table) {
if (!in_array($table, mapi_list_availables())) return array();
$table = preg_replace('/installed_/', '', $table);

$count = ORM::for_table($table)->count();
$count_results = NULL;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

$SearchQuery = NULL;
$LimitOffset = 0;

if (isset($_POST['limit_start']) && (intval($_POST['limit_start']) > 0) && is_int(intval($_POST['limit_start']))) {
$LimitOffset = ((intval($_POST['limit_start'])) - 1);
}

if (isset($_POST['limit_value']) && (intval($_POST['limit_value']) > 0) && is_int(intval($_POST['limit_value']))) {
$LimitValue = (intval($_POST['limit_value']));
} else {
$LimitValue = 250;
$_POST['limit_value'] = 250;
}

if (isset($_POST['keyword']) && strlen(trim($_POST['keyword'])) > 2) {
$searchstring = $_POST['keyword'];
$searchstring = str_replace(array('\'', '`'), array('\\\'', '\\`'), $searchstring);

$SearchQueryArray = explode(' ', $searchstring);

$SearchQuery = '((`text` LIKE \'%' . implode('%\' AND `text` LIKE \'%', $SearchQueryArray) . '%\')';
$SearchQuery .= ' OR ';
$SearchQuery .= '(`title` LIKE \'%' . implode('%\' AND `title` LIKE \'%', $SearchQueryArray) . '%\')';
$SearchQuery .= ' OR ';
$SearchQuery .= '(`address` LIKE \'%' . implode('%\' AND `address` LIKE \'%', $SearchQueryArray) . '%\'))';
//$SearchQuery .= ' AND (`type` = \'place\' OR `type` = \'event\' OR `type` = \'route\')';
}

if (isset($_POST['language']) && strlen(trim($_POST['language'])) == 2) {
if ($SearchQuery) { $SearchQuery .= ' AND '; }
$SearchQuery .= '(`language` LIKE \'' . trim($_POST['language']) . '\')';
}

if (isset($_POST['type']) && strlen(trim($_POST['type'])) > 1) {
if ($SearchQuery) { $SearchQuery .= ' AND '; }
$SearchQuery .= '(`type` LIKE \'' . trim($_POST['type']) . '\')';
}

if ($SearchQuery) {

$SearchQuery = 'WHERE ' . $SearchQuery;

if ((isset($_POST['location'])) && (strlen(trim($_POST['location'])) > 0) && (isset($_POST['lon'])) && (isset($_POST['radius'])) && (isset($_POST['lat'])) && (is_numeric($_POST['lon'])) && (is_numeric($_POST['lat'])) && (is_numeric($_POST['radius']))) {

$count_results = count(ORM::for_table('contents')
->raw_query('SELECT id, (3959 * acos(cos(radians(:latitude)) * cos(radians(lat)) * cos(radians(lng) - radians(:longitude)) + sin(radians(:latitude)) * sin(radians(lat)))) * 1000 AS distance FROM contents ' . $SearchQuery . ' HAVING distance < :radius AND distance > 0',
array("latitude" => $_POST["lat"], "longitude" => $_POST["lon"], "radius" => $_POST["radius"]))->find_many());

if ($count_results > 10) {
if ($LimitOffset > ($count_results - 10)) {
$LimitOffset = ($count_results - 10);
$_POST['limit_start'] = ($LimitOffset + 1);
}
} else {
$LimitOffset = 0;
$_POST['limit_start'] = ($LimitOffset + 1);
}

$results = ORM::for_table('contents')
->raw_query('SELECT id, type, title, address, hits, enabled, language, modified, (3959 * acos(cos(radians(:latitude)) * cos(radians(lat)) * cos(radians(lng) - radians(:longitude)) + sin(radians(:latitude)) * sin(radians(lat)))) * 1000 AS distance FROM contents ' . $SearchQuery . ' HAVING distance < :radius AND distance > 0 LIMIT ' . $LimitValue . ' OFFSET '. $LimitOffset,
array("latitude" => $_POST["lat"], "longitude" => $_POST["lon"], "radius" => $_POST["radius"]))->order_by_desc('id');

} else {

$SearchQuery = "SELECT id, type, title, address, hits, enabled, language, modified FROM $table " . $SearchQuery;
$count_results = count(ORM::for_table($table)->raw_query($SearchQuery)->find_many());

if ($count_results > 10) {
if ($LimitOffset > ($count_results - 10)) {
$LimitOffset = ($count_results - 10);
$_POST['limit_start'] = ($LimitOffset + 1);
}
} else {
$LimitOffset = 0;
$_POST['limit_start'] = ($LimitOffset + 1);
}

$SearchQuery = $SearchQuery . ' LIMIT ' . $LimitValue . ' OFFSET ' . $LimitOffset;
$results = ORM::for_table($table)->raw_query($SearchQuery)->order_by_desc('id');
}

} else {

if ((isset($_POST['location'])) && (strlen(trim($_POST['location'])) > 0) && (isset($_POST['lon'])) && (isset($_POST['radius'])) && (isset($_POST['lat'])) && (is_numeric($_POST['lon'])) && (is_numeric($_POST['lat'])) && (is_numeric($_POST['radius']))) {

$count_results = count(ORM::for_table('contents')
->raw_query('SELECT id, (3959 * acos(cos(radians(:latitude)) * cos(radians(lat)) * cos(radians(lng) - radians(:longitude)) + sin(radians(:latitude)) * sin(radians(lat)))) * 1000 AS distance FROM contents HAVING distance < :radius AND distance > 0',
array("latitude" => $_POST["lat"], "longitude" => $_POST["lon"], "radius" => $_POST["radius"]))->find_many());

if ($count_results > 10) {
if ($LimitOffset > ($count_results - 10)) {
$LimitOffset = ($count_results - 10);
$_POST['limit_start'] = ($LimitOffset + 1);
}
} else {
$LimitOffset = 0;
$_POST['limit_start'] = ($LimitOffset + 1);
}

$results = ORM::for_table('contents')
->raw_query('SELECT id, type, title, address, hits, enabled, language, modified, (3959 * acos(cos(radians(:latitude)) * cos(radians(lat)) * cos(radians(lng) - radians(:longitude)) + sin(radians(:latitude)) * sin(radians(lat)))) * 1000 AS distance FROM contents HAVING distance < :radius AND distance > 0 LIMIT ' . $LimitValue . ' OFFSET ' . $LimitOffset,
array("latitude" => $_POST["lat"], "longitude" => $_POST["lon"], "radius" => $_POST["radius"]))->order_by_desc('id');

} else {
$results = ORM::for_table($table)->select_many('id', 'type', 'title', 'address', 'hits', 'enabled', 'language', 'modified')->limit($LimitValue)->offset($LimitOffset)->order_by_desc('id');
}
}

} else {
$results = ORM::for_table($table)->select_many('id', 'type', 'title', 'address', 'hits', 'enabled', 'language', 'modified')->limit(250)->offset(0)->order_by_desc('id');
}

$Return['filtered_count'] = count($results->find_many());
if ($count_results) {
$Return['search_count'] = $count_results;
} else {
$Return['search_count'] = $count;
}
$Return['table'] = $results->find_many();
$Return['count'] = $count;

$Return['LangList'] = ORM::for_table('contents')->distinct()->select('language')->find_array();
$Return['TypeList'] = ORM::for_table('contents')->distinct()->select('type')->find_array();

return $Return;
}

function mapi_list( $what, $props = array() ) {
if ( ! in_array( $what, mapi_list_availables() ) ) return array();

Expand Down
34 changes: 34 additions & 0 deletions manager/modules/mcontent/ajax/GetAddressList.php
@@ -0,0 +1,34 @@
<?php

error_reporting( E_ALL );
ini_set( 'display_errors', 0 );

define( 'DACCESS', 1 );

define( 'APATH', dirname( __FILE__ ) );

$settings = APATH . '/../../../../settings.php';
$idiorm_lib = APATH . '/../../../../lib/idiorm/idiorm.php';

if ( ! is_file( $settings ) || ! is_readable( $settings ) ) die( 'M_ERROR (00110): A required file: settings.php is missing or not readable!' );
else include( $settings );

if ( ! is_file( $idiorm_lib ) || ! is_readable( $idiorm_lib ) ) die( 'M_ERROR (00111): A required file: idiorm.php is missing or not readable!' );
else include( $idiorm_lib );

ORM::configure('mysql:host=' . MSettings::$db_host . ';dbname=' . MSettings::$db);
ORM::configure('username', MSettings::$db_user);
ORM::configure('password', MSettings::$db_pass);
ORM::configure('return_result_sets', true); // returns result sets
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));

$string = strtolower($_GET["q"]);
if (!$string) return;

$TheData = ORM::for_table('contents')->distinct()->select('address')->where_like('address', '%'.$string.'%')->limit(20)->order_by_expr('CHAR_LENGTH(`address`)')->find_array();

foreach ($TheData as $key => $value) {
$cname = $value['address'];
echo "$cname\n";
}
?>
8 changes: 5 additions & 3 deletions manager/modules/mcontent/mcontent.php
Expand Up @@ -17,9 +17,11 @@ public function mcontent() {
}

public function content_list() {
$this->set_page_title( '#mappiamo - Contents list' );
$contents = $this->model( 'get_contents' );
$this->view( 'default', $contents );
$this->set_page_title('#mappiamo - Contents list');
//$contents = $this->model( 'get_contents' );
$contents = $this->model('filtered_content');
//print_r($contents); die();
$this->view('default', $contents);
}

public function content_add() {
Expand Down
4 changes: 4 additions & 0 deletions manager/modules/mcontent/models/mcontent.php
Expand Up @@ -5,6 +5,10 @@

class MModel_MContent {

static function filtered_content() {
return mapi_list_filtered('contents');
}

static function get_contents() {
return mapi_list( 'contents' );
}
Expand Down
98 changes: 97 additions & 1 deletion manager/modules/mcontent/views/default.php
Expand Up @@ -19,8 +19,104 @@

<?php MMessaging::show(); ?>

<hr><h3>You have <u>&Sigma; <?PHP echo $data['count']; ?></u> rows on content table.<br>
With current search criteria you have <u>&Sigma; <?PHP echo $data['search_count']; ?></u> data.</h3>

<form action="" method="POST" class="form-inline" id="contentlist_form">

<input type="hidden" name="mapi_csrf" id="mapi_csrf" value="<?php MPut::_html_attr( mapi_csrf_value() ); ?>" />
<input type="hidden" name="content_type" id="content_type" value="post" />

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-filter" title="Select type filter"></span></span>
<select name="type" class="form-control">
<option value="">Type...</option>

<?PHP foreach ($data['TypeList'] as $OneType) {

if (isset($_POST['type']) && $_POST['type'] == $OneType['type']) {
$SelectedString = ' SELECTED';
} else {
$SelectedString = NULL;
}

?>

<option value="<?PHP echo $OneType['type']; ?>"<?PHP echo $SelectedString; ?>><?PHP echo $OneType['type']; ?></option>

<?PHP } ?>

</select>
</div>

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search" title="Search by this keyword on title, text, and address"></span></span>
<input type="text" name="keyword" id="inputKeyword" placeholder="Keyword" class="form-control" <?PHP if (isset($_POST['keyword'])) { echo 'value="' . $_POST['keyword'] . '"'; } ?>>
</div>

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-map-marker" title="Define location for search"></span></span>
<input type="text" name="location" id="inputAddress" placeholder="Location" class="form-control" <?PHP if (isset($_POST['location'])) { echo 'value="' . $_POST['location'] . '"'; } ?>>
</div>

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-dashboard" title="Define radius from location as distance"></span></span>
<select name="radius" class="form-control">
<option value="1000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 1000) { echo ' selected'; } ?>>1 km</option>
<option value="2000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 2000) { echo ' selected'; } ?>>2 km</option>
<option value="5000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 5000) { echo ' selected'; } ?>>5 km</option>
<option value="10000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 10000) { echo ' selected'; } ?>>10 km</option>
<option value="20000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 20000) { echo ' selected'; } ?>>20 km</option>
<option value="50000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 50000) { echo ' selected'; } ?>>50 km</option>
<option value="100000"<?PHP if (isset($_POST['radius']) && $_POST['radius'] == 100000) { echo ' selected'; } ?>>100 km</option>
</select>
</div>

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-globe" title="Select language filter"></span></span>
<select name="language" class="form-control">
<option value="">Language...</option>

<?PHP foreach ($data['LangList'] as $OneLang) {

if (isset($_POST['language']) && $_POST['language'] == $OneLang['language']) {
$SelectedString = ' SELECTED';
} else {
$SelectedString = NULL;
}

?>

<option value="<?PHP echo $OneLang['language']; ?>"<?PHP echo $SelectedString; ?>><?PHP echo $OneLang['language']; ?></option>

<?PHP } ?>

</select>
</div>

<input type="hidden" id="content_listfilter_lat" name="lat" value="">
<input type="hidden" id="content_listfilter_lon" name="lon" value="">

<h3>Result limited to

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-list" title="Define the limit of list"></span></span>
<input type="number" min="10" step="10" max="2000" required name="limit_value" id="limit_value" placeholder="Limit" class="form-control" <?PHP if (isset($_POST['limit_value'])) { echo 'value=' . $_POST['limit_value'] . ''; } else { echo 'value=250'; } ?> style="width: 80px;">
</div>

rows, the list start from row:

<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-pushpin" title="Define the first row from the result list"></span></span>
<input type="number" min="1" step="1" max="<?PHP echo (($data['count']) - 10); ?>" required name="limit_start" id="limit_start" placeholder="Start" class="form-control" <?PHP if (isset($_POST['limit_start'])) { echo 'value=' . $_POST['limit_start'] . ''; } else { echo 'value=1'; } ?> style="width: 80px;">
</div>

<button type="submit" id="content_table_search" class="btn btn-primary">Show data</button></h3>

</form><hr>

<?php
MTable::init( $data, 'content_list' );
MTable::init($data['table'], 'content_list');
MTable::columns( array( 'id', 'title', 'type', 'hits', 'address', 'modified', 'language', 'enabled' ) );
MTable::links( array( 'title' => 'index.php?module=mcontent&task=content_edit&object=*[id]' ) );
MTable::badges( array( 'hits' ) );
Expand Down
2 changes: 1 addition & 1 deletion modules/event/ajax/GetAddressList.php
Expand Up @@ -25,7 +25,7 @@
$string = strtolower($_GET["q"]);
if (!$string) return;

$TheData = ORM::for_table('contents')->distinct()->select('address')->where('enabled', 1)->where('type', 'event')->find_array();
$TheData = ORM::for_table('contents')->distinct()->select('address')->where('enabled', 1)->where_like('address', '%'.$string.'%')->limit(20)->order_by_expr('CHAR_LENGTH(`address`)')->where('type', 'event')->find_array();

foreach ($TheData as $key => $value) {
$cname = $value['address'];
Expand Down

0 comments on commit 1245fb3

Please sign in to comment.