Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
This commit is contained in:
90
utilities/admin/fetchSysData.php
Normal file
90
utilities/admin/fetchSysData.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* fetchSysData.php
|
||||
*
|
||||
* Stub program that's invoked by gaAdmin utility.
|
||||
*
|
||||
* This program stub connects to the admin mongo resource and pulls all (the whole one record) of system data from
|
||||
* the system-data collection. (There should be either zero (edge case) or one record stored.)
|
||||
*
|
||||
* The program will store any user-level error messages in an array named $formErrors which will be displayed to the
|
||||
* user in the next page load.
|
||||
*
|
||||
* There is an edge case to be accommodated -- when you request to edit a new Namaste installation and there is no
|
||||
* data stored in the system-table.
|
||||
*
|
||||
* todo: write a program that populates the systemData collection during installation
|
||||
*
|
||||
* If data exists in the table, it's stored as an associative array in a variable called: $systemData.
|
||||
* If data doesn't exist in the table, and if no errors were generated, we're going to assume it's a new (unpopulated)
|
||||
* table. In both of the previous cases, a boolean value: $sysDataLoad is set to true.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-07-18 mks CORE-1113: original coding
|
||||
*
|
||||
*/
|
||||
$meta = [
|
||||
META_TEMPLATE => TEMPLATE_CLASS_SYS_EVENTS,
|
||||
META_CLIENT => CLIENT_SYSTEM,
|
||||
META_CLIENT_IP => STRING_SESSION_HOME,
|
||||
];
|
||||
if (!isset($data['c'])) {
|
||||
$systemMessage[] = 'Choice (C) data not loaded!';
|
||||
return;
|
||||
}
|
||||
$whichConstant = intval($data['c']);
|
||||
|
||||
// this script may only execute locally on the namaste admin service
|
||||
// todo -- remove the "true or" when done debugging
|
||||
//if (true or intval(gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_MONGODB][CONFIG_DATABASE_MONGODB_ADMIN][CONFIG_IS_LOCAL]) != 1) {
|
||||
if (intval(gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_MONGODB][CONFIG_DATABASE_MONGODB_ADMIN][CONFIG_IS_LOCAL]) != 1) {
|
||||
$formErrors[] = ERROR_LOCAL_NOT_ADMIN;
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate the systemData class object
|
||||
try {
|
||||
$obj = new gacFactory($meta, FACTORY_EVENT_NEW_CLASS, basename(__FILE__) . AT . __LINE__, $formErrors);
|
||||
} catch (TypeError $t) {
|
||||
$formErrors[] = ERROR_TYPE_EXCEPTION . COLON . $t->getMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure that the systemData class object successfully instantiated
|
||||
if (!$obj->status) {
|
||||
$formErrors = $obj->eventMessages;
|
||||
if (is_object($obj->widget)) $obj->widget->__destruct();
|
||||
if (is_object($obj)) $obj->__destruct();
|
||||
unset($obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch the systemData
|
||||
$query = [null];
|
||||
$obj->widget->_fetchRecords([STRING_QUERY_DATA => $query]);
|
||||
if (!$obj->status) {
|
||||
$formErrors = $obj->widget->eventMessages;
|
||||
if (is_object($obj->widget)) $obj->widget->__destruct();
|
||||
if (is_object($obj)) $obj->__destruct();
|
||||
unset($obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the data array
|
||||
$obj->widget->eventMessages = null;
|
||||
$systemData = $obj->widget->getData();
|
||||
if (is_array($systemData)) $systemData = $systemData[0];
|
||||
$sysDataLoad = (empty($obj->widget->eventMessages)) ? true : false;
|
||||
if (is_null($systemData) and $sysDataLoad) {
|
||||
$systemMessage[] = 'The system data table has not been created yet; the table will be created when the new data is saved.';
|
||||
} elseif (!$sysDataLoad) {
|
||||
$formErrors[] = $obj->widget->eventMessages;
|
||||
}
|
||||
if (is_object($obj->widget)) $obj->widget->__destruct();
|
||||
if (is_object($obj)) $obj->__destruct();
|
||||
unset($obj);
|
||||
71
utilities/admin/gaAdmin.js
Normal file
71
utilities/admin/gaAdmin.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* gaAdmin.js
|
||||
*
|
||||
* This is the javascript file for the Namaste admin web-program: gaAdmin.php.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-06-18 CORE-1113: original coding
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This stub handles the click event when a user clicks on the side-nav bar (Edit Constants) and selects the option
|
||||
* to edit either the STATE or STATUS constants. The stub evaluates which link was clicked and passes the result back
|
||||
* to the server via AJAX which, in turn, should spawn the events to fetch the systemData record and display the
|
||||
* appropriate data field on-screen.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-06-18 mks CORE-1113: original coding
|
||||
*
|
||||
*/
|
||||
$('.getSysD').on('click', function () {
|
||||
var id = this.id;
|
||||
var which = 0;
|
||||
|
||||
// console.log('id: ' + id);
|
||||
switch (id) {
|
||||
case 'stateConstants' :
|
||||
which = 'c=1';
|
||||
break;
|
||||
case 'statusConstants' :
|
||||
which = 'c=2';
|
||||
break;
|
||||
}
|
||||
|
||||
// console.log('which: ' + which);
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
$.ajax({
|
||||
type : "POST",
|
||||
data : which,
|
||||
success: function ( response ) {
|
||||
$('body').html(response);
|
||||
console.log(response);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// $( "#gaConstants" ).submit(function() {
|
||||
// alert( "Handler for .submit() called." );
|
||||
// // event.preventDefault();
|
||||
// $.ajax({
|
||||
// type : "POST",
|
||||
// data : 'stateConstants=1',
|
||||
// success: function () {
|
||||
// }
|
||||
// })
|
||||
// });
|
||||
81
utilities/admin/loadConstants.php
Normal file
81
utilities/admin/loadConstants.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* loadConstants.php
|
||||
*
|
||||
* This stub is called when a user selects the option to edit the state or status constants in namaste.
|
||||
*
|
||||
* We call this stub to generate the main panel (HTML) which is an editable table containing the data pulled from
|
||||
* the systemData collection -- depending on which link was clicked on the main page, we'll load either state or
|
||||
* status constants into the table.
|
||||
*
|
||||
* If there is no data in the system table, the system message will display that fact and we'll proc an empty table
|
||||
* for the user to begin population.
|
||||
*/
|
||||
|
||||
// state constants == 1
|
||||
// status constants == 2
|
||||
if (intval($data['c']) == 1) {
|
||||
$whichConstant = VALID_STATES;
|
||||
$constantTitle = 'States';
|
||||
} elseif (intval($data['c']) == 2) {
|
||||
$whichConstant = VALID_STATUS;
|
||||
$constantTitle = 'Status';
|
||||
} else {
|
||||
$systemMessage = 'Invalid data (status) choice!';
|
||||
return;
|
||||
}
|
||||
|
||||
$htmlMain = '
|
||||
<div class="col-md-5">
|
||||
<!-- Panel Header -->
|
||||
<div class="view view-cascade py-3 gradient-card-header info-color-dark">
|
||||
<h5>' . $whichConstant . '</h5>
|
||||
</div>
|
||||
|
||||
<!-- Panel Content -->
|
||||
<div class="card-body card-body-cascade">
|
||||
<!-- Grid Row -->
|
||||
<div class="row">
|
||||
<!-- Grid Column -->
|
||||
<div class="col-md-auto mb-4">
|
||||
<!-- Editable Table -->
|
||||
<div class="card">
|
||||
<h3 class="card-header text-center font-weight-bold text-uppercase py-4">' . $constantTitle . '</h3>
|
||||
<div class="card-body">
|
||||
<div id="constantTable" class="table-editable">
|
||||
<span class="table-add float-right mb-3 mr-2"><a href="#!" class="text-success">
|
||||
<i class="fa fa-plus fa-2x" aria-hidden="true"></i></a>
|
||||
</span>
|
||||
<table class="table table-bordered table-responsive-md table-striped text-center">
|
||||
<tr>
|
||||
<th class="text-center">Constant Key</th>
|
||||
<th class="text-center">Constant Value</th>
|
||||
<th class="text-center">Remove</th>
|
||||
</tr>
|
||||
|
||||
';
|
||||
|
||||
if (isset($systemData) and is_array($systemData)) {
|
||||
foreach ($systemData[$whichConstant] as $key => $value) {
|
||||
$htmlMain .= '<tr>';
|
||||
$htmlMain .= '<td class="pt-3-half" contenteditable="true">' . $key . '</td>';
|
||||
$htmlMain .= '<td class="pt-3-half" contenteditable="true">' . $value . '</td>';
|
||||
$htmlMain .= '<td><span class="table-remove"><button type="button" class="btn btn-danger btn-rounded btn-sm my-0">Remove</button></span></td>';
|
||||
$htmlMain .= '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$htmlMain .= '
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !Editable Table -->
|
||||
</div>
|
||||
<!-- !Grid Column -->
|
||||
</div>
|
||||
<!-- !Grid Row -->
|
||||
</div>
|
||||
<!-- !Panel Content -->
|
||||
';
|
||||
?>
|
||||
298
utilities/cachejefe.php
Normal file
298
utilities/cachejefe.php
Normal file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/**
|
||||
* cachejefe.php -- the 21st-Century Namaste Cache Manager!
|
||||
*
|
||||
* This program uses the Material-Design Bootstrap framework which is licensed to Micheal Shallop, personally, but can
|
||||
* can be distributed as a web-app under the developer license. (See the licensing files in ./html for more info)
|
||||
*
|
||||
* This program is a replacement for the old cache-manager program which has a stunning UI reminiscent of 2004. This
|
||||
* app could be a lot more ajax-y but I'm about as far as it gets from being a f/e dev so you gets what you gets.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-05-18 mks CORE-781: original coding
|
||||
* 08-29-18 mks DB-50: replaced boots with sneakers
|
||||
* 01-17-20 mks DB-150: squelching sneakerstrap stdout/stderr
|
||||
*
|
||||
*/
|
||||
|
||||
// initialization
|
||||
ob_start();
|
||||
require_once(dirname(__DIR__) . '/config/sneakerstrap.inc');
|
||||
ob_end_clean();
|
||||
ini_set('xdebug.var_display_max_depth', 10);
|
||||
ini_set('xdebug.var_display_max_children', 256);
|
||||
ini_set('xdebug.var_display_max_data', 1024);
|
||||
$data = (isset($_REQUEST['data'])) ? $_REQUEST['data'] : STRING_CACHE_HOME;
|
||||
$errorMessage = '';
|
||||
$cRecord = null;
|
||||
if (strlen($_REQUEST[STRING_CACHE_SEARCH])) {
|
||||
// search all the keys for the submitted search string
|
||||
$searchKey = htmlspecialchars($_REQUEST[STRING_CACHE_SEARCH]);
|
||||
$cKeys = gasCache::getAllKeys();
|
||||
$foundKeys = [];
|
||||
foreach($cKeys as $key) {
|
||||
if (stripos($key, $searchKey) !== false and (!in_array($key, $foundKeys))) {
|
||||
$foundKeys[] = $key;
|
||||
$tmp = "<a href='?data=delete&ckey=$key'><i class='fa fa-trash red-text'></i></a> ";
|
||||
$tmp .= "<a href='?data=fetch&ckey=$key'><i class='fa fa-eye'></i> </a> " . $key . "<br>";
|
||||
$keyData[] = $tmp;
|
||||
}
|
||||
}
|
||||
$keyCount = count($foundKeys);
|
||||
$data = STRING_CACHE_SEARCH;
|
||||
} else {
|
||||
// otherwise, they clicked on a nav-bar option
|
||||
switch ($data) {
|
||||
case STRING_CACHE_FETCH :
|
||||
$cRecord = gasCache::sysGet($_REQUEST[STRING_CACHE_CKEY]);
|
||||
if (!empty($cRecord) and !is_array($cRecord)) {
|
||||
$extractedData = json_decode(gzuncompress($cRecord), true);
|
||||
if (!is_null($extractedData))
|
||||
$cRecord = $extractedData;
|
||||
} elseif (empty($cRecord)) {
|
||||
$errorMessage = 'Data referenced by key no longer exists in-cache; the key may have expired.';
|
||||
}
|
||||
break;
|
||||
|
||||
case STRING_CACHE_FLUSH :
|
||||
$res = gasCache::flush_cache();
|
||||
$cRecord = 'Cache was ' . ((!$res) ? '<span class="red-text">NOT</span> ' : '') . 'flushed successfully!';
|
||||
break;
|
||||
|
||||
case STRING_CACHE_STATS :
|
||||
$cData = gasCache::get_stats();
|
||||
break;
|
||||
|
||||
case STRING_CACHE_DELETE :
|
||||
gasCache::sysDel($_REQUEST[STRING_CACHE_CKEY]);
|
||||
$delMsg = 'Key ' . $_REQUEST[STRING_CACHE_CKEY] . ' was deleted.';
|
||||
break;
|
||||
|
||||
case STRING_CACHE_KEYS :
|
||||
// get a list of all keys in cache
|
||||
$keyList = gasCache::getAllKeys();
|
||||
sort($keyList);
|
||||
$foundKeys = [];
|
||||
$counter = 1;
|
||||
$keyData = [];
|
||||
|
||||
if (is_array($keyList)) {
|
||||
foreach ($keyList as $cKey) {
|
||||
if (!in_array($cKey, $foundKeys)) {
|
||||
$foundKeys[] = $cKey;
|
||||
$tmp = "<a href='?data=delete&ckey=$cKey'><i class='fa fa-trash red-text'></i></a> ";
|
||||
$tmp .= "<a href='?data=fetch&ckey=$cKey'><i class='fa fa-eye'></i> </a> " . $cKey . "<br>";
|
||||
$keyData[] = $tmp;
|
||||
}
|
||||
}
|
||||
$keyCount = count($foundKeys);
|
||||
}
|
||||
break;
|
||||
|
||||
case STRING_CACHE_HOME :
|
||||
; // do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Namaste Tools: Cache Jefe</title>
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="../html/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Material Design Bootstrap -->
|
||||
<link href="../html/css/mdb.min.css" rel="stylesheet">
|
||||
<!-- Your custom styles (optional) -->
|
||||
<link href="../html/css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg justify-content-between navbar-dark blue-gradient">
|
||||
<a class="navbar-brand" href="#">
|
||||
<!--suppress CheckImageSize -->
|
||||
<img src="../html/img/namaste.png" height="50" alt="">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false"
|
||||
aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="cachejefeNav">
|
||||
<form method="post" action="">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item <?php if ($data == STRING_CACHE_HOME) echo 'active'; ?>">
|
||||
<a class="nav-link" href="?data=home">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item <?php if ($data == STRING_CACHE_KEYS) echo 'active'; ?>">
|
||||
<a class="nav-link" href="?data=keys">Keys </a>
|
||||
</li>
|
||||
<li class="nav-item <?php if ($data == STRING_CACHE_STATS) echo 'active'; ?>">
|
||||
<a class="nav-link" href="?data=stats">Stats </a>
|
||||
</li>
|
||||
<li class="nav-item <?php if ($data == STRING_CACHE_FLUSH) echo 'active'; ?>">
|
||||
<a class="nav-link" href="?data=flush">Flush </a>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</div>
|
||||
<!-- search box -->
|
||||
<form method="post" action="" class="form-inline my-0">
|
||||
<div class="md-form form-sm mt-0">
|
||||
<input class="form-control form-control-sm mr-sm-2 mb-0" name="keyHash" type="text" maxlength="100" placeholder="Search (partials accepted)" aria-label="Search">
|
||||
</div>
|
||||
<button class="btn btn-outline-white btn-sm my-0" type="submit">Search</button>
|
||||
</form>
|
||||
</nav>
|
||||
<?php
|
||||
switch ($data) {
|
||||
case STRING_CACHE_HOME :
|
||||
echo
|
||||
'<div style="height: 50vh">
|
||||
<div class="flex-center flex-column">
|
||||
<h1 class="animated fadeIn mb-4">Namaste Cache Jefe</h1>
|
||||
<h5 class="animated fadeIn mb-3">Diagnostic and Debugging Tool</h5>
|
||||
<p class="animated fadeIn text-muted">Making cache your bitch since 2011!</p>
|
||||
|
||||
<div class="text-left flex-column">
|
||||
<br><br>
|
||||
<p><strong>Home </strong>displays this page</p>
|
||||
<p><strong>Keys </strong>lists all of the available keys currently stored in cache</p>
|
||||
<p><strong>Stats </strong>displays cache stats output which as some useful information</p>
|
||||
<p><strong>Flush </strong>flushes cache and <strong class="red-text">deletes </strong>ALL keys</p>
|
||||
<p><strong>Search </strong>allows you to search by all or part of a cache key</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
case STRING_CACHE_FETCH :
|
||||
case STRING_CACHE_FLUSH :
|
||||
echo
|
||||
'<div class="container-fluid">
|
||||
<div class="card">
|
||||
<h4 class="card-body">
|
||||
<div class="card-title"><strong>';
|
||||
if ($data == STRING_CACHE_FETCH)
|
||||
echo 'Cached Content for ' . $_REQUEST[STRING_CACHE_CKEY];
|
||||
else
|
||||
echo 'Cache Flush Request';
|
||||
echo '</strong>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="card-text" style="margin-left:10px;">';
|
||||
|
||||
if (!is_null($cRecord) and is_array($cRecord))
|
||||
var_dump($cRecord);
|
||||
elseif (false !== $cRecord and is_scalar($cRecord))
|
||||
echo $cRecord . '<br><br>';
|
||||
elseif (!empty($errorMessage))
|
||||
echo "<div class='text-danger'>" . $errorMessage . "</div>";
|
||||
else
|
||||
echo "<div class='text-danger'>" . ERROR_UNKNOWN_EVENT . $data . "</div>";
|
||||
echo '</div></div></div>';
|
||||
|
||||
break;
|
||||
case STRING_CACHE_STATS :
|
||||
echo
|
||||
'<br><div class="container-fluid">
|
||||
<div class="flex-center flex-column">
|
||||
<div class="card">
|
||||
<h4 class="card-body ">
|
||||
<strong>
|
||||
<div class="card-title">Cache Stats</div>
|
||||
</strong>
|
||||
<span class="card-text">';
|
||||
if (is_array($cData)) {
|
||||
var_dump($cData);
|
||||
} else {
|
||||
echo "Could not retrieve cache stats";
|
||||
}
|
||||
echo '
|
||||
</span>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
case STRING_CACHE_SEARCH :
|
||||
case STRING_CACHE_KEYS :
|
||||
case STRING_CACHE_DELETE :
|
||||
?>
|
||||
<br><br>
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<?php
|
||||
if ($data == STRING_CACHE_KEYS) {
|
||||
echo '<h5 class="card-title">Current Cached Key Count:' . $keyCount . '</h5>';
|
||||
} elseif ($data == STRING_CACHE_DELETE) {
|
||||
echo '<h5 class="card-title">' . $delMsg . '</h5>';
|
||||
} else {
|
||||
echo '<h5 class="card-title">Cached Key Search Results Count: ' . $keyCount . '</h5>';
|
||||
}
|
||||
?>
|
||||
<span class="card-text">
|
||||
<?php
|
||||
if ($data != STRING_CACHE_DELETE) {
|
||||
if ($keyCount) {
|
||||
echo "Click the <i class='fa fa-trash red-text'></i> to delete a cached record. ";
|
||||
echo "Click the <i class='fa fa-eye blue-text'></i> to view the cached record.";
|
||||
} else {
|
||||
if ($data == STRING_CACHE_KEYS) {
|
||||
echo 'There are no records currently stored in the cache system.';
|
||||
} else {
|
||||
echo 'Search request: "' . $searchKey . '", returned no data.';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<br><br>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<?php
|
||||
for ($index = 0; $index < $keyCount; $index+=3) {
|
||||
echo '<div class="row">' . $eos;
|
||||
if (!empty($keyData[$index]))
|
||||
echo '<div class="col">' . $keyData[$index] . '</div>' . $eos;
|
||||
if (!empty($keyData[($index + 1)]))
|
||||
echo '<div class="col">' . $keyData[$index+1] . '</div>' . $eos;
|
||||
if (!empty($keyData[($index + 2)]))
|
||||
echo '<div class="col">' . $keyData[$index+2] . '</div>' . $eos;
|
||||
echo '</div>' . $eos;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- SCRIPTS -->
|
||||
<!-- JQuery -->
|
||||
<script type="text/javascript" src="../html/js/jquery-3.2.1.min.js"></script>
|
||||
<!-- Bootstrap tooltips -->
|
||||
<script type="text/javascript" src="../html/js/popper.min.js"></script>
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script type="text/javascript" src="../html/js/bootstrap.js"></script>
|
||||
<!-- MDB core JavaScript -->
|
||||
<script type="text/javascript" src="../html/js/mdb.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
206
utilities/cashpeak.php
Normal file
206
utilities/cashpeak.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* memcache reader utility
|
||||
*
|
||||
* load it - it's self documenting...
|
||||
*
|
||||
* todo: convert to MDB
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0.0
|
||||
*
|
||||
* HISTORY:
|
||||
* --------
|
||||
* 07-14-17 mks CORE-470: initial coding
|
||||
*
|
||||
*/
|
||||
|
||||
// initialization
|
||||
require_once(dirname(__DIR__) . '/config/bootstrap.inc');
|
||||
|
||||
$sizeA = 0;
|
||||
$sizeB = 0;
|
||||
|
||||
$keyCount = 0;
|
||||
$idHash = null;
|
||||
$errorMsg = null;
|
||||
$hashKey = null;
|
||||
$data = '';
|
||||
|
||||
//get current maintenance mode status
|
||||
if (!empty($_REQUEST['maintenanceMessage'])) {
|
||||
gasCache::add('maintenance', gzcompress(json_encode(['maintenanceMessage' => $_REQUEST['maintenanceMessage']])));
|
||||
}
|
||||
|
||||
if ($maintenance = gasCache::get('maintenance')) {
|
||||
if ($maintenance !== 1) {
|
||||
$maintenance = json_decode(gzuncompress($maintenance), true);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['admin'])) {
|
||||
switch ($_REQUEST['admin']) {
|
||||
case 'getKeys' :
|
||||
$info = gasCache::getAllKeys();
|
||||
$data = '';
|
||||
$foundKeys = array();
|
||||
if (is_array($info)) {
|
||||
sort($info);
|
||||
foreach($info as $row) {
|
||||
if (!in_array($row, $foundKeys)) {
|
||||
$keyCount++;
|
||||
$data .= "<a class='delete' href='?idhash=$row&delete=1'></a>";
|
||||
$data .= "<a class='cachekey' href='?idhash=$row'>$row</a>";
|
||||
$data .= '<br>';
|
||||
$foundKeys[] = $row;
|
||||
}
|
||||
}
|
||||
$data .= '<br><br><br>';
|
||||
$data = 'Key Count: ' . $keyCount . '<br><br>' . $data;
|
||||
}
|
||||
break;
|
||||
case 'getStats' :
|
||||
$data = gasCache::get_stats();
|
||||
break;
|
||||
case 'doFlush' :
|
||||
gasCache::flush_cache();
|
||||
$data = 'Cache has been flushed';
|
||||
break;
|
||||
case 'doDeleteAll':
|
||||
$keys = gasCache::getAllKeys();
|
||||
if (is_array($keys)) {
|
||||
foreach($keys as $key)
|
||||
{
|
||||
if(!gasCache::delete($key))
|
||||
echo "Could not delete one of the keys";
|
||||
}
|
||||
echo "Deleted all keys!";
|
||||
}
|
||||
break;
|
||||
case 'toggleMaintenance':
|
||||
if($maintenance) {
|
||||
gasCache::delete('maintenance');
|
||||
} else {
|
||||
gasCache::add('maintenance', gzcompress(true));
|
||||
}
|
||||
header("Location: ".$_SERVER['SCRIPT_NAME']."?admin=getKeys"); die;
|
||||
break;
|
||||
}
|
||||
} elseif (isset($_REQUEST['idhash'], $_REQUEST['delete'])) {
|
||||
$key = $_REQUEST['idhash'];
|
||||
if(!gasCache::delete($key))
|
||||
$errorMsg[] = 'Could not delete: ' . $key;
|
||||
else {
|
||||
header("Location: ".$_SERVER['SCRIPT_NAME']."?admin=getKeys"); die;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['idhash'])) {
|
||||
$eClass = '';
|
||||
$idHash = htmlspecialchars(trim($_REQUEST['idhash']));
|
||||
$allKeys = empty($info) ? gasCache::getAllKeys() : $info;
|
||||
|
||||
$data = '';
|
||||
$multi = '';
|
||||
$realHash = '';
|
||||
$foundKeys = array();
|
||||
foreach($allKeys as $key) {
|
||||
if (stripos($key, $idHash) !== false and (!in_array($key, $foundKeys))) {
|
||||
$foundKeys[] = $key;
|
||||
$multi .= "<a class='delete' href='?idhash=$key&delete=1'></a>";
|
||||
$multi .= "<a class='cachekey' href='?idhash=$key'>$key</a>";
|
||||
$multi .= '<br>';
|
||||
|
||||
// Side effect is that only the first instance gets saved to $data
|
||||
// but it doesn't matter because if there is more than on e instance
|
||||
// we display all of the instances ($multi) instead of the details
|
||||
if(empty($data)) {
|
||||
$realHash = (strlen($idHash) > 30) ? $key : $idHash; // save the real $idHash of what we might be displaying the details of
|
||||
$data = gasCache::get($realHash);
|
||||
if (is_null($data)) {
|
||||
$data = gasCache::sysGet($realHash);
|
||||
} else {
|
||||
$sizeB = strlen(serialize($data));
|
||||
$data = json_decode(gzuncompress($data), true);
|
||||
$sizeA = strlen(serialize($data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(substr_count($multi, '<br>') > 1)
|
||||
$data = $multi;
|
||||
else
|
||||
$idHash = $realHash; // We display the $idHash in the details so display what
|
||||
// the real $idHash is, not what they were looking for
|
||||
|
||||
|
||||
if(empty($data)) {
|
||||
$data = 'key not found in-cache: ' . $idHash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<title>Cash Peak - Better than a ATM!</title>
|
||||
<link rel="stylesheet" href="logger.css" type="text/css">
|
||||
</HEAD>
|
||||
<body>
|
||||
<div class="title">
|
||||
Cash Peak
|
||||
</div>
|
||||
<div class="container">
|
||||
<form method="POST" action="">
|
||||
<fieldset>
|
||||
<legend>Cash Commands</legend>
|
||||
<a href='?admin=getKeys'>Get All Keys</a><br>
|
||||
<a href='?admin=getStats'>Get Cache Stats</a><br>
|
||||
<a href='?admin=doFlush'>Flush Cache</a><br>
|
||||
<a href='?admin=doDeleteAll'>Delete All Keys</a><br>
|
||||
<a href='?admin=toggleMaintenance'>Toggle Maintenance Mode</a> (Status: <?=!empty($maintenance) ? 'ON' : 'OFF'?>)<br/><br/>
|
||||
<textarea rows="3" style="-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;width: 100%;" name="maintenanceMessage" placeholder="Enter maintenance message here..."><?= !empty($maintenance['maintenanceMessage']) ? $maintenance['maintenanceMessage'] : '' ?></textarea><br/>
|
||||
<br>
|
||||
<input type="submit" value="Set message"/><br/>
|
||||
</fieldset>
|
||||
<br>
|
||||
<label>Find HashToken:</label>
|
||||
<input type="text" name="idhash" size="50%" placeholder=" ...also accepts partial tokens...">
|
||||
<button type="submit">fetch!</button>
|
||||
</form>
|
||||
<div class="rowError">
|
||||
<?php
|
||||
if (is_array($errorMsg)) {
|
||||
foreach($errorMsg as $row) {
|
||||
echo $row . '<br>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="rowData">
|
||||
<?php
|
||||
if (!empty($data)) {
|
||||
if (is_array($data)) {
|
||||
if (!empty($idHash))
|
||||
echo '<div>Hash Key: ' . $realHash . '</div>';
|
||||
if ($sizeA and $sizeB) {
|
||||
echo '<div>Size In-Cache: ' . $sizeB . '</div>';
|
||||
echo '<div>Size In-Memory: ' . $sizeA . '</div>';
|
||||
echo '<div>Compression: ' . sprintf('%2.2f',(($sizeA - $sizeB) / $sizeA) * 100) . '%</div>';
|
||||
}
|
||||
echo "<pre>";
|
||||
var_export($data); // use this one only if you've tweaked your var-dump depth
|
||||
echo "</pre>";
|
||||
} elseif (!empty($realHash)) {
|
||||
echo '<div>Output for: ' . $realHash . COLON;
|
||||
echo $data;
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div
|
||||
</div>
|
||||
</body>
|
||||
</HTML>
|
||||
258
utilities/ddbtp.php
Normal file
258
utilities/ddbtp.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* DynamoDB Template Processor
|
||||
*
|
||||
* in this first version, we're only going to create new tables from the template files...
|
||||
*
|
||||
* -- added code to properly handle secondary indices with error checking and verbose error messaging
|
||||
* -- cannot create a table if it already exists in the database; you must first delete a table
|
||||
* before creating if if pre-exists unless you're executing this script in a development environment AND
|
||||
* you've specified the "--delete" command line option.
|
||||
*
|
||||
* Delete a table from the command line:
|
||||
* aws dynamodb delete-table --table-name development_gaLogs --endpoint-url http://localhost:8000
|
||||
*
|
||||
* List tables from the command line:
|
||||
* aws dynamodb list-tables --endpoint-url http://localhost:8000
|
||||
*
|
||||
* Describe a table:
|
||||
* aws dynamodb describe-table --table-name development_gaLogs_log --endpoint-url http://localhost:8000
|
||||
*
|
||||
* Help with ddb indexes:
|
||||
* https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html
|
||||
*
|
||||
*
|
||||
* @author mike@givingassitant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-13-17 mks original coding
|
||||
* 06-27-17 mks processing for secondary indices
|
||||
* development-env bypass for deleting an existing table
|
||||
* 06-28-17 mks ensured that attribute keys are not duplicated,
|
||||
* added check for template type == TEMPLATE_DB_DDB,
|
||||
* added check that if secondary index, then the hash key is same as base index hash key
|
||||
* 07-10-18 mks CORE-773: replaced file-logging output with consoleLog()
|
||||
*
|
||||
*/
|
||||
use Aws\DynamoDb\Exception\DynamoDbException;
|
||||
|
||||
$_REDIRECT=false; // enable stdout
|
||||
$opts = getopt("", [ "delete::" ]);
|
||||
$eos = (isset($_SERVER['HTTP_USER_AGENT'])) ? '<br />' : PHP_EOL;
|
||||
$topDir = dirname( __DIR__ );
|
||||
|
||||
// load the files stored in the common directory
|
||||
foreach(glob($topDir . '/common/*.php') as $filename) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require_once($filename);
|
||||
}
|
||||
$classesDir = $topDir . DIR_CLASSES;
|
||||
$configDir = $topDir . DIR_CONFIG;
|
||||
$amqpLib = $topDir . DIR_LIB;
|
||||
$templateDir = $topDir . DIR_CLASSES . DIR_TEMPLATE;
|
||||
$logDir = $topDir . DIR_LOGS;
|
||||
date_default_timezone_set(STRING_SYS_TZ);
|
||||
$eol = "\n";
|
||||
$res = 'DDBC: ';
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require($topDir . FILE_AUTOLOADER);
|
||||
if(file_exists($classesDir)) {
|
||||
Autoloader::register_directory($classesDir);
|
||||
Autoloader::register_directory($templateDir);
|
||||
}
|
||||
require_once $amqpLib . '/vendor/autoload.php';
|
||||
|
||||
//load the base config
|
||||
gasConfig::singleton($configDir . FILE_BASE_CONFIG, FILE_TYPE_XML);
|
||||
// layer the env config
|
||||
if (file_exists($configDir . FILE_ENV_CONFIG)) {
|
||||
gasConfig::addConfig($configDir . FILE_ENV_CONFIG, FILE_TYPE_XML);
|
||||
}
|
||||
|
||||
// environment matters
|
||||
$validEnvs = [ ENV_DEVELOPMENT, ENV_STAGING, ENV_PRODUCTION ];
|
||||
$env = gasConfig::$settings[CONFIG_ID][CONFIG_ID_ENV];
|
||||
if (!in_array($env, $validEnvs)) {
|
||||
consoleLog($res, CON_ERROR, ERROR_ENV_INVALID . $env);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// check to see if user is requesting to hard-delete existing table(s)
|
||||
$hardDelete = (array_key_exists('delete', $opts)) ? true : false; // won't work with a constant
|
||||
// safety net to ensure that we cannot hard-delete a table in a non-development environment
|
||||
if ($env != ENV_DEVELOPMENT) $hardDelete = false;
|
||||
|
||||
$errors = null;
|
||||
consoleLog($res, CON_SUCCESS, sprintf(INFO_TEMPLATE_PROCESSING_STARTED, CONFIG_DATABASE_DDB));
|
||||
|
||||
/** @var Aws\DynamoDb\DynamoDbClient $ddbConnection */
|
||||
$ddbConnection = gasResourceManager::fetchResource(RESOURCE_DDB);
|
||||
|
||||
if (is_null($ddbConnection)) {
|
||||
consoleLog($res, CON_ERROR, ERROR_DDB_CONNECT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// first, let's get a list of all the existing tables...
|
||||
$result = $ddbConnection->listTables();
|
||||
$meta = $result->get(DDB_METADATA);
|
||||
if ($meta[DDB_STATUS_CODE] != NUMBER_HTTP_SUCCESS) {
|
||||
consoleLog($res, CON_ERROR, ERROR_DDB_QUERY . 'listTables()');
|
||||
exit(1);
|
||||
}
|
||||
$tableList = $result->get(DDB_TABLE_NAMES);
|
||||
if (!sizeof($tableList)) $tableList = null;
|
||||
|
||||
$pt = [
|
||||
DDB_STRING_READ_CAPACITY_UNITS => gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_DDB][CONFIG_DATABASE_READ_CAPACITY_UNITS],
|
||||
DDB_STRING_WRITE_CAPACITY_UNITS => gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_DDB][CONFIG_DATABASE_WRITE_CAPACITY_UNITS]
|
||||
];
|
||||
$counter = 0;
|
||||
$deleteCounter = 0;
|
||||
foreach(glob(dirname(__DIR__) . DIR_CLASSES . DIR_TEMPLATE . STRING_CLASS_FILE_GAT . '*' . STRING_CLASS_FILE_EXT) as $filename) {
|
||||
$currentClass = basename($filename);
|
||||
$currentClass = preg_replace("/" . STRING_CLASS_FILE_EXT . "/", "", $currentClass);
|
||||
consoleLog($res, CON_SUCCESS, INFO_PROCESSING . $currentClass);
|
||||
try {
|
||||
/** @var gatLogs() $tmpObj */
|
||||
$tmpObj = new $currentClass();
|
||||
} catch (Exception $e) {
|
||||
consoleLog($res, CON_ERROR, $e->getMessage());
|
||||
}
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if ($tmpObj->schema != TEMPLATE_DB_DDB) break; // skip if not a DDB template
|
||||
$iKeys = array_keys($tmpObj->indexes);
|
||||
$schema = null;
|
||||
$gsi = null; // global secondary indexes
|
||||
$lsi = null; // local secondary indexes
|
||||
$attrDefs = null;
|
||||
$baseHashName = '';
|
||||
$uniqAttrList = null;
|
||||
// process template directives for base index
|
||||
for ($index = 0; $index < sizeof($tmpObj->indexes); $index++) {
|
||||
$uniqAttrList[] = $iKeys[$index] . $tmpObj->extension;
|
||||
if ($tmpObj->indexes[$iKeys[$index]] == DDB_INDEX_HASH) $baseHashName = $iKeys[$index];
|
||||
$schema[] = [DDB_STRING_ATTRIBUTE_NAME => $iKeys[$index] . $tmpObj->extension, DDB_STRING_KEY_TYPE => $tmpObj->indexes[$iKeys[$index]]];
|
||||
$attrDefs[] = [DDB_STRING_ATTRIBUTE_NAME => $iKeys[$index] . $tmpObj->extension, DDB_STRING_ATTRIBUTE_TYPE => $tmpObj->fields[$iKeys[$index]]];
|
||||
}
|
||||
// process directives for secondary indexes
|
||||
$indexList = [ DDB_STRING_GSI, DDB_STRING_LSI ];
|
||||
// loop to process the template's global and then the secondary index array structures
|
||||
foreach ($indexList as $thisIndex) {
|
||||
$ti = null; // this index
|
||||
$requiredFieldList = [STRING_NAME, STRING_INDEXES, DDB_STRING_PT];
|
||||
$ptValues = [ DDB_PT_KEYS_ONLY, DDB_PT_INCLUDE, DDB_PT_ALL ];
|
||||
for ($index = 0, $c = count($tmpObj->$thisIndex); $index < $c; $index++) {
|
||||
$nka = null;
|
||||
$projection = null;
|
||||
$keySchema = null;
|
||||
if (!empty($tmpObj->$thisIndex[$index][DDB_STRING_NON_KEY_ATTRIBUTE])
|
||||
and is_array($tmpObj->$thisIndex[$index][DDB_STRING_NON_KEY_ATTRIBUTE])
|
||||
) {
|
||||
$nka = $tmpObj->$thisIndex[$index][DDB_STRING_NON_KEY_ATTRIBUTE];
|
||||
}
|
||||
if (!in_array($tmpObj->$thisIndex[$index][DDB_STRING_PT], $ptValues)) {
|
||||
consoleLog($res, CON_ERROR, '(' . $thisIndex . ')::Invalid index projection type: ' . $tmpObj->$thisIndex[$index][DDB_STRING_PT]);
|
||||
exit(1);
|
||||
}
|
||||
$projection = [DDB_STRING_PROJECTION_TYPE => $tmpObj->$thisIndex[$index][DDB_STRING_PT]];
|
||||
if (!is_null($nka) and $tmpObj->$thisIndex[$index][DDB_STRING_PT] == DDB_PT_INCLUDE) {
|
||||
$attrList = null;
|
||||
// append the class extension to the non-key attributes in a projection
|
||||
foreach ($tmpObj->$thisIndex[$index][DDB_STRING_NON_KEY_ATTRIBUTE] as $attribute)
|
||||
$attrList[] = $attribute . $tmpObj->extension;
|
||||
$projection[DDB_STRING_NON_KEY_ATTRIBUTES] = $attrList;
|
||||
// $projection[DDB_STRING_NON_KEY_ATTRIBUTES] = $tmpObj->$thisIndex[$index][DDB_STRING_NON_KEY_ATTRIBUTE];
|
||||
} elseif (!is_null($nka)) {
|
||||
consoleLog($res, CON_ERROR, 'Ignored non-key-attribute list because projection type is: ' . $tmpObj->$thisIndex[$index][DDB_STRING_PT]);
|
||||
}
|
||||
$ti[$index] = [
|
||||
DDB_STRING_INDEX_NAME => $tmpObj->$thisIndex[$index][STRING_NAME],
|
||||
DDB_STRING_PROJECTION => $projection,
|
||||
];
|
||||
$c2 = 0;
|
||||
foreach ($tmpObj->$thisIndex[$index][STRING_INDEXES] as $ik => $iv) {
|
||||
if ($thisIndex == DDB_STRING_LSI and $iv == DDB_INDEX_HASH and $ik != $baseHashName) {
|
||||
consoleLog($res, CON_ERROR, 'Template error: a secondary index must have the same HASH key as the base index!');
|
||||
consoleLog($res, CON_ERROR, 'Check template: ' . $filename . ': ' . $thisIndex . ' and correct');
|
||||
exit(1);
|
||||
}
|
||||
$keySchema[$c2++] = [ DDB_STRING_ATTRIBUTE_NAME => ($ik . $tmpObj->extension), DDB_STRING_KEY_TYPE => $iv ];
|
||||
if (!in_array(($ik . $tmpObj->extension), $uniqAttrList)) {
|
||||
$uniqAttrList[] = ($ik . $tmpObj->extension);
|
||||
$attrDefs[] = [DDB_STRING_ATTRIBUTE_NAME => $ik . $tmpObj->extension, DDB_STRING_ATTRIBUTE_TYPE => $tmpObj->fields[$ik]];
|
||||
}
|
||||
}
|
||||
$ti[$index][DDB_STRING_KEY_SCHEMA] = $keySchema;
|
||||
if (isset($tmpObj->$thisIndex[$index][STRING_THROUGHPUT]) and $thisIndex == DDB_STRING_GSI) {
|
||||
$ti[$index][DDB_STRING_PROVISIONED_THROUGHPUT][DDB_STRING_READ_CAPACITY_UNITS] = $tmpObj->$thisIndex[$index][STRING_THROUGHPUT][CONFIG_DATABASE_READ_CAPACITY_UNITS];
|
||||
$ti[$index][DDB_STRING_PROVISIONED_THROUGHPUT][DDB_STRING_WRITE_CAPACITY_UNITS] = $tmpObj->$thisIndex[$index][STRING_THROUGHPUT][CONFIG_DATABASE_WRITE_CAPACITY_UNITS];
|
||||
} elseif (isset($tmpObj->$thisIndex[$index][STRING_THROUGHPUT]) and $thisIndex == DDB_STRING_LSI) {
|
||||
consoleLog($res, CON_ERROR, 'Detected throughput provisioning for local secondary index which is not allowed.');
|
||||
consoleLog($res, CON_ERROR, 'Check configuration for index: ' . $tmpObj->$thisIndex[$index][STRING_NAME]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ($thisIndex == DDB_STRING_GSI) $gsi = $ti;
|
||||
if ($thisIndex == DDB_STRING_LSI) $lsi = $ti;
|
||||
}
|
||||
$tn = $env . UDASH . $tmpObj->collection . $tmpObj->extension;
|
||||
$newt = [
|
||||
DDB_STRING_TABLE_NAME => $tn,
|
||||
DDB_STRING_KEY_SCHEMA => $schema,
|
||||
DDB_STRING_ATTRIBUTE_DEFINITIONS => $attrDefs,
|
||||
DDB_STRING_PROVISIONED_THROUGHPUT => $pt
|
||||
];
|
||||
if (!is_null($gsi)) $newt[DDB_STRING_GLOBAL_SI] = $gsi;
|
||||
if (!is_null($lsi)) $newt[DDB_STRING_LOCAL_SI] = $lsi;
|
||||
|
||||
// to be able to delete a table, we must be in development env and explicitly passed the --delete option
|
||||
$exec = true;
|
||||
if (in_array($tn, $tableList) and gasConfig::$settings[CONFIG_ID][CONFIG_ID_ENV] != ENV_DEVELOPMENT) {
|
||||
consoleLog($res, CON_ERROR, 'Table: ' . $tn . ' already exists in the database...skipping...');
|
||||
consoleLog($res, CON_ERROR, 'You must remove a table before you can create it.');
|
||||
$exec = false;
|
||||
} elseif (gasConfig::$settings[CONFIG_ID][CONFIG_ID_ENV] == ENV_DEVELOPMENT and $hardDelete and in_array($tn, $tableList)) {
|
||||
consoleLog($res, CON_SYSTEM, 'Table: ' . $tn . ' already exists, but you have authorized it to be deleted.');
|
||||
try {
|
||||
$res = $ddbConnection->deleteTable([DDB_STRING_TABLE_NAME => $tn]);
|
||||
consoleLog($res, CON_SUCCESS, 'Successfully deleted table: ' . $tn);
|
||||
$deleteCounter++;
|
||||
} catch (DynamoDbException $e) {
|
||||
consoleLog($res, CON_ERROR, "Failed to create table: " . $tn);
|
||||
consoleLog($res, CON_ERROR, $e->getMessage());
|
||||
exit(1);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
consoleLog($res, CON_ERROR, "Failed to create table: " . $tn);
|
||||
consoleLog($res, CON_ERROR, $e->getMessage());
|
||||
// print_r($newt);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ($exec) {
|
||||
try {
|
||||
$res = $ddbConnection->createTable($newt);
|
||||
consoleLog($res, CON_SUCCESS, 'Successfully created table: ' . $tn);
|
||||
$counter++;
|
||||
} catch (DynamoDbException $e) {
|
||||
consoleLog($res, CON_ERROR, 'Failed to create table: ' . $tn);
|
||||
consoleLog($res, CON_ERROR, $e->getMessage());
|
||||
// print_r($newt);
|
||||
exit(1);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
consoleLog($res, CON_ERROR, 'Failed to create table: ' . $tn);
|
||||
consoleLog($res, CON_ERROR, $e->getMessage());
|
||||
// print_r($newt);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($deleteCounter) {
|
||||
consoleLog($res, CON_SYSTEM, 'deleted ' . $deleteCounter . ' tables...');
|
||||
}
|
||||
consoleLog($res, CON_SUCCESS, 'created ' . $counter . ' tables... ');
|
||||
exit(0);
|
||||
207
utilities/deprecated/cashpeak.php.old
Normal file
207
utilities/deprecated/cashpeak.php.old
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* memcache reader utility
|
||||
*
|
||||
* load it - it's self documenting...
|
||||
*
|
||||
* todo: convert to MDB
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* --------
|
||||
* 07-14-17 mks CORE-470: initial coding
|
||||
*
|
||||
*/
|
||||
|
||||
// initialization
|
||||
require_once(dirname(__DIR__) . '/config/bootstrap.inc');
|
||||
|
||||
$sizeA = 0;
|
||||
$sizeB = 0;
|
||||
|
||||
$keyCount = 0;
|
||||
$idHash = null;
|
||||
$errorMsg = null;
|
||||
$hashKey = null;
|
||||
$data = '';
|
||||
$info = null;
|
||||
|
||||
//get current maintenance mode status
|
||||
if (!empty($_REQUEST['maintenanceMessage'])) {
|
||||
gasCache::add('maintenance', gzcompress(json_encode(['maintenanceMessage' => $_REQUEST['maintenanceMessage']])));
|
||||
}
|
||||
|
||||
if ($maintenance = gasCache::get('maintenance')) {
|
||||
if ($maintenance !== 1) {
|
||||
$maintenance = json_decode(gzuncompress($maintenance), true);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['admin'])) {
|
||||
switch ($_REQUEST['admin']) {
|
||||
case 'getKeys' :
|
||||
$info = gasCache::getAllKeys();
|
||||
$data = '';
|
||||
$foundKeys = array();
|
||||
if (is_array($info)) {
|
||||
sort($info);
|
||||
foreach($info as $row) {
|
||||
if (!in_array($row, $foundKeys)) {
|
||||
$keyCount++;
|
||||
$data .= "<a class='delete' href='?idhash=$row&delete=1'></a>";
|
||||
$data .= "<a class='cachekey' href='?idhash=$row'>$row</a>";
|
||||
$data .= '<br>';
|
||||
$foundKeys[] = $row;
|
||||
}
|
||||
}
|
||||
$data .= '<br><br><br>';
|
||||
$data = 'Key Count: ' . $keyCount . '<br><br>' . $data;
|
||||
}
|
||||
break;
|
||||
case 'getStats' :
|
||||
$data = gasCache::get_stats();
|
||||
break;
|
||||
case 'doFlush' :
|
||||
gasCache::flush_cache();
|
||||
$data = 'Cache has been flushed';
|
||||
break;
|
||||
case 'doDeleteAll':
|
||||
$keys = gasCache::getAllKeys();
|
||||
if (is_array($keys)) {
|
||||
foreach($keys as $key)
|
||||
{
|
||||
if(!gasCache::delete($key))
|
||||
echo "Could not delete one of the keys";
|
||||
}
|
||||
echo "Deleted all keys!";
|
||||
}
|
||||
break;
|
||||
case 'toggleMaintenance':
|
||||
if($maintenance) {
|
||||
gasCache::delete('maintenance');
|
||||
} else {
|
||||
gasCache::add('maintenance', gzcompress(true));
|
||||
}
|
||||
header("Location: ".$_SERVER['SCRIPT_NAME']."?admin=getKeys"); die;
|
||||
break;
|
||||
}
|
||||
} elseif (isset($_REQUEST['idhash'], $_REQUEST['delete'])) {
|
||||
$key = $_REQUEST['idhash'];
|
||||
if(!gasCache::delete($key))
|
||||
$errorMsg[] = 'Could not delete: ' . $key;
|
||||
else {
|
||||
header("Location: ".$_SERVER['SCRIPT_NAME']."?admin=getKeys"); die;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['idhash'])) {
|
||||
$eClass = '';
|
||||
$idHash = htmlspecialchars(trim($_REQUEST['idhash']));
|
||||
$allKeys = empty($info) ? gasCache::getAllKeys() : $info;
|
||||
|
||||
$data = '';
|
||||
$multi = '';
|
||||
$realHash = '';
|
||||
$foundKeys = array();
|
||||
foreach($allKeys as $key) {
|
||||
if (stripos($key, $idHash) !== false and (!in_array($key, $foundKeys))) {
|
||||
$foundKeys[] = $key;
|
||||
$multi .= "<a class='delete' href='?idhash=$key&delete=1'></a>";
|
||||
$multi .= "<a class='cachekey' href='?idhash=$key'>$key</a>";
|
||||
$multi .= '<br>';
|
||||
|
||||
// Side effect is that only the first instance gets saved to $data
|
||||
// but it doesn't matter because if there is more than on e instance
|
||||
// we display all of the instances ($multi) instead of the details
|
||||
if(empty($data)) {
|
||||
$realHash = (strlen($idHash) > 30) ? $key : $idHash; // save the real $idHash of what we might be displaying the details of
|
||||
$data = gasCache::get($realHash);
|
||||
if (is_null($data)) {
|
||||
$data = gasCache::sysGet($realHash);
|
||||
} else {
|
||||
$sizeB = strlen(serialize($data));
|
||||
$data = json_decode(gzuncompress($data), true);
|
||||
$sizeA = strlen(serialize($data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(substr_count($multi, '<br>') > 1)
|
||||
$data = $multi;
|
||||
else
|
||||
$idHash = $realHash; // We display the $idHash in the details so display what
|
||||
// the real $idHash is, not what they were looking for
|
||||
|
||||
|
||||
if(empty($data)) {
|
||||
$data = 'key not found in-cache: ' . $idHash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<title>Cash Peak - Better than a ATM!</title>
|
||||
<link rel="stylesheet" href="logger.css" type="text/css">
|
||||
</HEAD>
|
||||
<body>
|
||||
<div class="title">
|
||||
Cash Peak
|
||||
</div>
|
||||
<div class="container">
|
||||
<form method="POST" action="">
|
||||
<fieldset>
|
||||
<legend>Cash Commands</legend>
|
||||
<a href='?admin=getKeys'>Get All Keys</a><br>
|
||||
<a href='?admin=getStats'>Get Cache Stats</a><br>
|
||||
<a href='?admin=doFlush'>Flush Cache</a><br>
|
||||
<a href='?admin=doDeleteAll'>Delete All Keys</a><br>
|
||||
<a href='?admin=toggleMaintenance'>Toggle Maintenance Mode</a> (Status: <?=!empty($maintenance) ? 'ON' : 'OFF'?>)<br/><br/>
|
||||
<textarea rows="3" style="-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;width: 100%;" name="maintenanceMessage" placeholder="Enter maintenance message here..."><?= !empty($maintenance['maintenanceMessage']) ? $maintenance['maintenanceMessage'] : '' ?></textarea><br/>
|
||||
<br>
|
||||
<input type="submit" value="Set message"/><br/>
|
||||
</fieldset>
|
||||
<br>
|
||||
<label>Find HashToken:</label>
|
||||
<input type="text" name="idhash" size="50%" placeholder=" ...also accepts partial tokens...">
|
||||
<button type="submit">fetch!</button>
|
||||
</form>
|
||||
<div class="rowError">
|
||||
<?php
|
||||
if (is_array($errorMsg)) {
|
||||
foreach($errorMsg as $row) {
|
||||
echo $row . '<br>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="rowData">
|
||||
<?php
|
||||
if (!empty($data)) {
|
||||
if (is_array($data)) {
|
||||
if (!empty($idHash))
|
||||
echo '<div>Hash Key: ' . $realHash . '</div>';
|
||||
if ($sizeA and $sizeB) {
|
||||
echo '<div>Size In-Cache: ' . $sizeB . '</div>';
|
||||
echo '<div>Size In-Memory: ' . $sizeA . '</div>';
|
||||
echo '<div>Compression: ' . sprintf('%2.2f',(($sizeA - $sizeB) / $sizeA) * 100) . '%</div>';
|
||||
}
|
||||
echo "<pre>";
|
||||
var_export($data); // use this one only if you've tweaked your var-dump depth
|
||||
echo "</pre>";
|
||||
} elseif (!empty($realHash)) {
|
||||
echo '<div>Output for: ' . $realHash . COLON;
|
||||
echo $data;
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div
|
||||
</div>
|
||||
</body>
|
||||
</HTML>
|
||||
63
utilities/dumper.php
Normal file
63
utilities/dumper.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
// initialization
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
ob_start();
|
||||
require_once(dirname(__DIR__) . '/config/sneakerstrap.inc');
|
||||
ob_end_clean();
|
||||
$logger = new gacErrorLogger();
|
||||
|
||||
$lines = 100;
|
||||
if (isset($_GET['lines'])) {
|
||||
if (is_numeric($_GET['lines'])) {
|
||||
if ($_GET['lines'] < 0) {
|
||||
$lines = 100;
|
||||
} else {
|
||||
$lines = intval($_GET['lines']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$where = TEMPLATE_CLASS_LOGS;
|
||||
if (isset($_GET['source'])) {
|
||||
$where = $_GET['source'];
|
||||
}
|
||||
$dataDump = $logger->getLog($lines, $where);
|
||||
?>
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<title>GA Log Dumper - Go ahead - Take a dump!</title>
|
||||
<link rel="stylesheet" href="logger.css" type="text/css">
|
||||
</HEAD>
|
||||
<body>
|
||||
<div class="title">
|
||||
GA Dump of: <?= $where?> Collection
|
||||
</div>
|
||||
<div class="container">
|
||||
<form method="get" action="dumper.php">
|
||||
<input type="radio" value="Logs" name="source" checked> Logs
|
||||
<input type="radio" value="Metrics" name="source"> Metrics
|
||||
Lines to Display: <input type="text" value="100" size="5" name="lines">
|
||||
<button type="submit">Go</button>
|
||||
</form>
|
||||
<div>
|
||||
<?php
|
||||
if (gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_QUERY_TIMERS] == 1) {
|
||||
$msg = sprintf(INFO_SLOW_QUERY_TIMERS, STRING_ENABLED) . sprintf(INFO_QUERY_TIMER_VALUES, gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_TIMER_SLOW_QUERY_ALERT]);
|
||||
echo $msg . $eos;
|
||||
$msg = sprintf(INFO_SLOW_QUERY_TIMER_WARNINGS, STRING_ENABLED) . sprintf(INFO_QUERY_TIMER_VALUES, gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_TIMER_SLOW_QUERY_WARNING]);
|
||||
echo $msg . $eos;
|
||||
} else {
|
||||
$msg = sprintf(INFO_SLOW_QUERY_TIMERS, STRING_DISABLED);
|
||||
echo $msg . $eos;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<?php
|
||||
echo (empty($dataDump)) ? 'No data found in GA collection:' . $where : $dataDump;
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</HTML>
|
||||
835
utilities/gaAdmin.php
Normal file
835
utilities/gaAdmin.php
Normal file
@@ -0,0 +1,835 @@
|
||||
<?php
|
||||
/**
|
||||
* gaAdmin -- the Namaste Admin program
|
||||
*
|
||||
* This program provides the administrative interface for Namaste - it is a single-script PHP program that utilizes
|
||||
* Material-Design Bootstrap framework and template. (Licensed to Micheal Shallop/Single-Project) See the licensing
|
||||
* doc in ./html for more info.
|
||||
*
|
||||
* The program self-processes user-input and allows for:
|
||||
*
|
||||
* a) updating some table-based data used in Namaste
|
||||
* b) dashboard of generalized Namaste activity
|
||||
*
|
||||
* Over time, additional functionality will be added as required. For now, the main purpose of the program is to allow
|
||||
* the Namaste admin an easy way to edit db data values, and passively view the state of Namaste.
|
||||
*
|
||||
* This script will only run from the admin service and so required a web-service to be installed.
|
||||
*
|
||||
* Programmer Notes:
|
||||
* -----------------
|
||||
* This project is incomplete - it requires someone much more adept (which is pretty much anyone) at f/e programming
|
||||
* than myself. The sub-directory (./utilities/admin) contains additional scripts/programs for this main program.
|
||||
*
|
||||
* The MDB libs are in ./html and are licensed to me for this project. I acquired the admin-theme for this project
|
||||
* and it's doc is at: https://mdbootstrap.com/product/admin-theme/
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-03-18 mks CORE-1113: Initial coding.
|
||||
*
|
||||
*/
|
||||
|
||||
// initialization
|
||||
require_once(dirname(__DIR__) . '/config/sneakerstrap.inc');
|
||||
|
||||
$systemMessage = [];
|
||||
$formErrors = [];
|
||||
$data = $_POST;
|
||||
$formStatus = false;
|
||||
$sysDataLoad = false;
|
||||
$formState = STATE_DATA_ERROR;
|
||||
|
||||
if (!is_null($data) and isset($data['c'])) {
|
||||
require_once('admin/fetchSysData.php');
|
||||
}
|
||||
// request to manipulate constants (state/status)
|
||||
if (isset($data['c']) and $sysDataLoad) {
|
||||
switch (intval($data['c'])) {
|
||||
case 1 :
|
||||
// state constants
|
||||
case 2 :
|
||||
// status constants
|
||||
require_once('admin/loadConstants.php');
|
||||
break;
|
||||
default :
|
||||
$systemMessage[] = 'received a bad parameter for constants - could not load constant data';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Material Design Bootstrap</title>
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="../html/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Material Design Bootstrap -->
|
||||
<link href="../html/css/mdb.min.css" rel="stylesheet">
|
||||
<!-- Your custom styles (optional) -->
|
||||
<link href="../html/css/style.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body class="fixed-sn indigo-skin">
|
||||
|
||||
<!--Main Navigation-->
|
||||
<header>
|
||||
|
||||
<!--Navbar-->
|
||||
<nav class="navbar navbar-expand-lg justify-content-between double-nav fixed-top navbar-dark blue-gradient">
|
||||
|
||||
<!-- SideNav slide-out button -->
|
||||
<div class="float-left">
|
||||
<a href="#" data-activates="slide-out" class="button-collapse">
|
||||
<i class="fa fa-bars"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Breadcrumb-->
|
||||
<div class="breadcrumb-dn mr-auto darken-1">
|
||||
<p>Namaste Administration</p>
|
||||
</div>
|
||||
|
||||
<!-- Links -->
|
||||
<ul class="nav navbar-nav nav-flex-icons ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">
|
||||
<i class="fa fa-envelope"></i>
|
||||
<span class="clearfix d-none d-sm-inline-block">Contact</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">
|
||||
<i class="fa fa-gear"></i>
|
||||
<span class="clearfix d-none d-sm-inline-block">Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-user"></i>
|
||||
<span class="clearfix d-none d-sm-inline-block">Account</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!--/.Navbar-->
|
||||
|
||||
<!-- Sidebar navigation -->
|
||||
<div id="slide-out" class="side-nav fixed">
|
||||
<ul class="custom-scrollbar list-unstyled">
|
||||
<!-- Logo -->
|
||||
<li class="logo-sn waves-effect">
|
||||
<div class=" text-center">
|
||||
<a href="#" class="pl-0">
|
||||
<img src="../html/img/namaste.png" height="50" alt="">
|
||||
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<!--/. Logo -->
|
||||
<!--Search Form-->
|
||||
<li>
|
||||
<form class="search-form" role="search">
|
||||
<div class="md-form my-0 waves-light">
|
||||
<input type="text" class="form-control py-2" placeholder="Search">
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
<!--/.Search Form-->
|
||||
<!-- Side navigation links -->
|
||||
<li>
|
||||
<ul class="collapsible collapsible-accordion">
|
||||
<li>
|
||||
<a class="collapsible-header waves-effect arrow-r">
|
||||
<i class="fa fa-gear"></i> Edit Constants
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</a>
|
||||
<div class="collapsible-body">
|
||||
<ul>
|
||||
<!-- <form id="gaConstants" action="" method="post">-->
|
||||
<form id="gaConstants" action="">
|
||||
<li>
|
||||
<!--<a href="javascript:void(0);" onclick="$('#gaConstants').submit()" id="stateConstants" class="getSysD waves-effect">State Constants</a>-->
|
||||
<a href="javascript:void(0);" id="stateConstants" class="getSysD waves-effect">State Constants</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:void(0);" id="statusConstants" class="getSysD waves-effect">Status Constants</a>
|
||||
<!--<a href="javascript:void(0);" onclick="$('#gaConstants').submit()" id="statusConstants" class="getSysD waves-effect">Status Constants</a>-->
|
||||
</li>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="collapsible-header waves-effect arrow-r">
|
||||
<i class="fa fa-hand-pointer-o"></i> Instruction
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</a>
|
||||
<div class="collapsible-body">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">For bloggers</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">For authors</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="collapsible-header waves-effect arrow-r">
|
||||
<i class="fa fa-eye"></i> About
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</a>
|
||||
<div class="collapsible-body">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">Introduction</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">Monthly meetings</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="collapsible-header waves-effect arrow-r">
|
||||
<i class="fa fa-envelope-o"></i> Contact me
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</a>
|
||||
<div class="collapsible-body">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">FAQ</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="waves-effect">Write a message</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/. Side navigation links -->
|
||||
</ul>
|
||||
|
||||
<!-- Mask -->
|
||||
<div class="sidenav-bg mask-strong"></div>
|
||||
|
||||
</div>
|
||||
<!--/. Sidebar navigation -->
|
||||
|
||||
</header>
|
||||
<!--Main Navigation-->
|
||||
|
||||
<!--Main layout-->
|
||||
<main>
|
||||
<div class="container-fluid">
|
||||
|
||||
<!--Section: Modals-->
|
||||
<section>
|
||||
|
||||
<!--Modal: modalConfirmDelete-->
|
||||
<div class="modal fade" id="modalConfirmDelete" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm modal-notify modal-danger" role="document">
|
||||
<!--Content-->
|
||||
<div class="modal-content text-center">
|
||||
<!--Header-->
|
||||
<div class="modal-header d-flex justify-content-center">
|
||||
<p class="heading">Are you sure?</p>
|
||||
</div>
|
||||
|
||||
<!--Body-->
|
||||
<div class="modal-body">
|
||||
|
||||
<i class="fa fa-times fa-4x animated rotateIn"></i>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Footer-->
|
||||
<div class="modal-footer flex-center">
|
||||
<a href="https://mdbootstrap.com/product/material-design-for-bootstrap-pro/" class="btn btn-danger">Yes</a>
|
||||
<a type="button" class="btn btn-outline-danger waves-effect" data-dismiss="modal">No</a>
|
||||
</div>
|
||||
</div>
|
||||
<!--/.Content-->
|
||||
</div>
|
||||
</div>
|
||||
<!--Modal: modalConfirmDelete-->
|
||||
|
||||
</section>
|
||||
<!--Section: Modals-->
|
||||
|
||||
<!--Section: Main panel-->
|
||||
<section class="card card-cascade narrower mb-5">
|
||||
|
||||
<!--Grid row-->
|
||||
<div class="row">
|
||||
|
||||
<!-- MAIN PANEL BEGINS HERE -->
|
||||
<?php
|
||||
// if (!empty($systemMessage)) echo $systemMessage;
|
||||
if (!empty($htmlMain)) {
|
||||
echo $htmlMain;
|
||||
}
|
||||
?>
|
||||
<!-- MAIN PANEL ENDS HERE -->
|
||||
</div>
|
||||
<!--Grid row-->
|
||||
|
||||
</section>
|
||||
<!--Section: Main panel-->
|
||||
|
||||
<!--Section: Table-->
|
||||
<section class="mb-5">
|
||||
|
||||
<!--Top Table UI-->
|
||||
<div class="card p-2 mb-5">
|
||||
|
||||
<!--Grid row-->
|
||||
<div class="row">
|
||||
|
||||
<!--Grid column-->
|
||||
<div class="col-lg-3 col-md-12">
|
||||
|
||||
<!--Name-->
|
||||
<select class="mdb-select colorful-select dropdown-primary mx-2">
|
||||
<option value="" disabled selected>Bulk actions</option>
|
||||
<option value="1">Delete</option>
|
||||
<option value="2">Export</option>
|
||||
<option value="3">Change segment</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<!--Grid column-->
|
||||
|
||||
<!--Grid column-->
|
||||
<div class="col-lg-3 col-md-6">
|
||||
|
||||
<!--Blue select-->
|
||||
<select class="mdb-select colorful-select dropdown-primary mx-2">
|
||||
<option value="" disabled selected>Show only</option>
|
||||
<option value="1">All
|
||||
<span> (2000)</span>
|
||||
</option>
|
||||
<option value="2">Never opened
|
||||
<span> (200)</span>
|
||||
</option>
|
||||
<option value="3">Opened but unanswered
|
||||
<span> (1800)</span>
|
||||
</option>
|
||||
<option value="4">Answered
|
||||
<span> (200)</span>
|
||||
</option>
|
||||
<option value="5">Unsunscribed
|
||||
<span> (50)</span>
|
||||
</option>
|
||||
</select>
|
||||
<!--/Blue select-->
|
||||
|
||||
</div>
|
||||
<!--Grid column-->
|
||||
|
||||
<!--Grid column-->
|
||||
<div class="col-lg-3 col-md-6">
|
||||
|
||||
<!--Blue select-->
|
||||
<select class="mdb-select colorful-select dropdown-primary mx-2">
|
||||
<option value="" disabled selected>Filter segments</option>
|
||||
<option value="1">Contacts in no segments
|
||||
<span> (100)</span>
|
||||
</option>
|
||||
<option value="1">Segment 1
|
||||
<span> (2000)</span>
|
||||
</option>
|
||||
<option value="2">Segment 2
|
||||
<span> (1000)</span>
|
||||
</option>
|
||||
<option value="3">Segment 3
|
||||
<span> (4000)</span>
|
||||
</option>
|
||||
</select>
|
||||
<!--/Blue select-->
|
||||
|
||||
</div>
|
||||
<!--Grid column-->
|
||||
|
||||
<!--Grid column-->
|
||||
<div class="col-lg-3 col-md-6">
|
||||
|
||||
<form class="md-form form-inline mt-2 ml-2">
|
||||
<input class="form-control my-0" type="text" placeholder="Search" style="max-width: 150px;">
|
||||
<button class="btn btn-sm btn-info ml-2 px-2">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<!--Grid column-->
|
||||
|
||||
</div>
|
||||
<!--Grid row-->
|
||||
|
||||
</div>
|
||||
<!--Top Table UI-->
|
||||
|
||||
<!--Card-->
|
||||
<div class="card card-cascade narrower">
|
||||
|
||||
<!--Card header-->
|
||||
<div class="view view-cascade py-3 gradient-card-header info-color-dark mx-4 d-flex justify-content-between align-items-center">
|
||||
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-white btn-rounded btn-sm px-2">
|
||||
<i class="fa fa-th-large mt-0"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-white btn-rounded btn-sm px-2">
|
||||
<i class="fa fa-columns mt-0"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<a href="" class="white-text mx-3">Table name</a>
|
||||
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-white btn-rounded btn-sm px-2">
|
||||
<i class="fa fa-pencil mt-0"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-white btn-rounded btn-sm px-2" data-toggle="modal" data-target="#modalConfirmDelete">
|
||||
<i class="fa fa-remove mt-0"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-white btn-rounded btn-sm px-2">
|
||||
<i class="fa fa-info-circle mt-0"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--/Card header-->
|
||||
|
||||
<!--Card content-->
|
||||
<div class="card-body card-body-cascade">
|
||||
|
||||
<div class="table-responsive">
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<input class="form-check-input" type="checkbox" id="checkbox">
|
||||
<label for="checkbox" class="label-table form-check-label"></label>
|
||||
</th>
|
||||
<th class="th-lg">First column</th>
|
||||
<th class="th-lg">Second column</th>
|
||||
<th class="th-lg">Third column</th>
|
||||
<th class="th-lg">Fourth column</th>
|
||||
<th class="th-lg">Fifth column</th>
|
||||
<th class="th-lg">Sixth column</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<input class="form-check-input" type="checkbox" id="checkbox1">
|
||||
<label for="checkbox1" class="label-table form-check-label"></label>
|
||||
</th>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<input class="form-check-input" type="checkbox" id="checkbox2">
|
||||
<label for="checkbox2" class="label-table form-check-label"></label>
|
||||
</th>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<input class="form-check-input" type="checkbox" id="checkbox3">
|
||||
<label for="checkbox3" class="label-table form-check-label"></label>
|
||||
</th>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
<td>Lorem Ipsum</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<hr class="my-0">
|
||||
|
||||
<!--Bottom Table UI-->
|
||||
<div class="d-flex justify-content-between">
|
||||
|
||||
<!--Name-->
|
||||
<select class="mdb-select colorful-select dropdown-primary mt-2 hidden-md-down">
|
||||
<option value="" disabled>Rows number</option>
|
||||
<option value="1" selected>10 rows</option>
|
||||
<option value="2">25 rows</option>
|
||||
<option value="3">50 rows</option>
|
||||
<option value="4">100 rows</option>
|
||||
</select>
|
||||
|
||||
<!--Pagination -->
|
||||
<nav class="my-4">
|
||||
<ul class="pagination pagination-circle pg-blue mb-0">
|
||||
|
||||
<!--First-->
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link">First</a>
|
||||
</li>
|
||||
|
||||
<!--Arrow left-->
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!--Numbers-->
|
||||
<li class="page-item active">
|
||||
<a class="page-link">1</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link">2</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link">3</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link">4</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link">5</a>
|
||||
</li>
|
||||
|
||||
<!--Arrow right-->
|
||||
<li class="page-item">
|
||||
<a class="page-link" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!--First-->
|
||||
<li class="page-item">
|
||||
<a class="page-link">Last</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
<!--/Pagination -->
|
||||
|
||||
</div>
|
||||
<!--Bottom Table UI-->
|
||||
|
||||
</div>
|
||||
<!--/.Card content-->
|
||||
|
||||
</div>
|
||||
<!--/.Card-->
|
||||
|
||||
</section>
|
||||
<!--Section: Table-->
|
||||
|
||||
<!--Section: Accordion-->
|
||||
<section class="mb-5">
|
||||
|
||||
<!--Accordion wrapper-->
|
||||
<div class="accordion" id="accordionEx" role="tablist" aria-multiselectable="true">
|
||||
|
||||
<!-- Accordion card -->
|
||||
<div class="card">
|
||||
|
||||
<!-- Card header -->
|
||||
<div class="card-header" role="tab" id="headingOne">
|
||||
|
||||
<!--Options-->
|
||||
<div class="dropdown pull-left">
|
||||
<button class="btn btn-info btn-sm m-0 mr-3 p-2 dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-info">
|
||||
<a class="dropdown-item" href="#">Add new</a>
|
||||
<a class="dropdown-item" href="#">Rename folder</a>
|
||||
<a class="dropdown-item" href="#">Delete folder</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Heading -->
|
||||
<a id="folder-1" data-toggle="collapse" data-parent="#accordionEx" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||
<h5 class="mt-1 mb-0">
|
||||
<span>Folder 1</span>
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</h5>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Card body -->
|
||||
<div id="collapseOne" class="collapse show" role="tabpanel" aria-labelledby="headingOne">
|
||||
<div class="card-body">
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute,
|
||||
non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch
|
||||
3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda
|
||||
shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt
|
||||
sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
|
||||
farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
|
||||
labore sustainable VHS.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accordion card -->
|
||||
|
||||
<!-- Accordion card -->
|
||||
<div class="card">
|
||||
|
||||
<!-- Card header -->
|
||||
<div class="card-header" role="tab" id="headingTwo">
|
||||
|
||||
<!--Options-->
|
||||
<div class="dropdown pull-left">
|
||||
<button class="btn btn-info btn-sm m-0 mr-3 p-2 dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-info">
|
||||
<a class="dropdown-item" href="#">Add new</a>
|
||||
<a class="dropdown-item" href="#">Rename folder</a>
|
||||
<a class="dropdown-item" href="#">Delete folder</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Heading -->
|
||||
<a id="folder-2" data-toggle="collapse" data-parent="#accordionEx" href="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
|
||||
<h5 class="mt-1 mb-0">
|
||||
<span>Folder 2</span>
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</h5>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Card body -->
|
||||
<div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="headingTwo">
|
||||
<div class="card-body">
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute,
|
||||
non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch
|
||||
3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda
|
||||
shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt
|
||||
sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
|
||||
farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
|
||||
labore sustainable VHS.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accordion card -->
|
||||
|
||||
<!-- Accordion card -->
|
||||
<div class="card">
|
||||
|
||||
<!-- Card header -->
|
||||
<div class="card-header" role="tab" id="headingThree">
|
||||
|
||||
<!--Options-->
|
||||
<div class="dropdown pull-left">
|
||||
<button class="btn btn-info btn-sm m-0 mr-3 p-2 dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-info">
|
||||
<a class="dropdown-item" href="#">Add new</a>
|
||||
<a class="dropdown-item" href="#">Rename folder</a>
|
||||
<a class="dropdown-item" href="#">Delete folder</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Heading -->
|
||||
<a id="folder-3" data-toggle="collapse" data-parent="#accordionEx" href="#collapseThree" aria-expanded="true" aria-controls="collapseThree">
|
||||
<h5 class="mt-1 mb-0">
|
||||
<span>Folder 3</span>
|
||||
<i class="fa fa-angle-down rotate-icon"></i>
|
||||
</h5>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Card body -->
|
||||
<div id="collapseThree" class="collapse" role="tabpanel" aria-labelledby="headingThree">
|
||||
<div class="card-body">
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute,
|
||||
non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch
|
||||
3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda
|
||||
shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt
|
||||
sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer
|
||||
farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus
|
||||
labore sustainable VHS.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Accordion card -->
|
||||
</div>
|
||||
<!--/.Accordion wrapper-->
|
||||
|
||||
</section>
|
||||
<!--Section: Accordion-->
|
||||
|
||||
</div>
|
||||
</main>
|
||||
<!--Main layout-->
|
||||
|
||||
<!--Footer-->
|
||||
<footer class="page-footer mt-4">
|
||||
|
||||
<!--Copyright-->
|
||||
<div class="footer-copyright text-center py-3">
|
||||
<div class="container-fluid">
|
||||
© 2018 Copyright:
|
||||
<a href="https://www.givvingassistant.org"> GivingAssistant.org </a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!--/.Copyright-->
|
||||
|
||||
</footer>
|
||||
<!--/.Footer-->
|
||||
|
||||
<!-- SCRIPTS -->
|
||||
<!-- JQuery -->
|
||||
<script type="text/javascript" src="../html/js/jquery-3.3.1.min.js"></script>
|
||||
<!-- Bootstrap tooltips -->
|
||||
<script type="text/javascript" src="../html/js/popper.min.js"></script>
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script type="text/javascript" src="../html/js/bootstrap.min.js"></script>
|
||||
<!-- MDB core JavaScript -->
|
||||
<script type="text/javascript" src="../html/js/mdb.min.js"></script>
|
||||
<!-- gaAdmin JS Processing Script -->
|
||||
<script type="text/javascript" src="admin/gaAdmin.js"></script>
|
||||
|
||||
<!-- Initializations -->
|
||||
<script>
|
||||
// SideNav Initialization
|
||||
$(".button-collapse").sideNav();
|
||||
|
||||
// Material Select Initialization
|
||||
$(document).ready(function () {
|
||||
$('.mdb-select').material_select();
|
||||
});
|
||||
|
||||
// Data Picker Initialization
|
||||
$('.datepicker').pickadate();
|
||||
|
||||
// Tooltip Initialization
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Charts -->
|
||||
<script>
|
||||
// Minimalist chart
|
||||
$(function () {
|
||||
$('.min-chart#chart-sales').easyPieChart({
|
||||
barColor: "#4caf50",
|
||||
onStep: function (from, to, percent) {
|
||||
$(this.el).find('.percent').text(Math.round(percent));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Main chart
|
||||
// var ctxL = document.getElementById("lineChart").getContext('2d');
|
||||
// var myLineChart = new Chart(ctxL, {
|
||||
// type: 'line',
|
||||
// data: {
|
||||
// labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||
// datasets: [{
|
||||
// label: "My First dataset",
|
||||
// fillColor: "#fff",
|
||||
// backgroundColor: 'rgba(255, 255, 255, .3)',
|
||||
// borderColor: 'rgba(255, 255, 255)',
|
||||
// data: [0, 10, 5, 2, 20, 30, 45],
|
||||
// }]
|
||||
// },
|
||||
// options: {
|
||||
// legend: {
|
||||
// labels: {
|
||||
// fontColor: "#fff",
|
||||
// }
|
||||
// },
|
||||
// scales: {
|
||||
// xAxes: [{
|
||||
// gridLines: {
|
||||
// display: true,
|
||||
// color: "rgba(255,255,255,.25)"
|
||||
// },
|
||||
// ticks: {
|
||||
// fontColor: "#fff",
|
||||
// },
|
||||
// }],
|
||||
// yAxes: [{
|
||||
// display: true,
|
||||
// gridLines: {
|
||||
// display: true,
|
||||
// color: "rgba(255,255,255,.25)"
|
||||
// },
|
||||
// ticks: {
|
||||
// fontColor: "#fff",
|
||||
// },
|
||||
// }],
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
</script>
|
||||
|
||||
<!-- Alerts -->
|
||||
<script>
|
||||
$(function () {
|
||||
$('#folder-1').click(function () {
|
||||
toastr.error("Folder 1 has been clicked!", "Folder 1", {
|
||||
"positionClass": "toast-top-right",
|
||||
});
|
||||
});
|
||||
$('#folder-2').click(function () {
|
||||
// make it not disappear
|
||||
toastr.info("Folder 2 has been clicked!", "Folder 2", );
|
||||
});
|
||||
$('#folder-3').click(function () {
|
||||
// make it not disappear
|
||||
toastr.info("Folder 3 has been clicked!", "Folder 3", );
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
utilities/images/comp025.jpg
Normal file
BIN
utilities/images/comp025.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
utilities/images/delete-icon.png
Normal file
BIN
utilities/images/delete-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
utilities/images/edit.png
Normal file
BIN
utilities/images/edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
BIN
utilities/images/help_icon.gif
Normal file
BIN
utilities/images/help_icon.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
utilities/images/lblue047.gif
Normal file
BIN
utilities/images/lblue047.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
BIN
utilities/images/lgrey064.jpg
Normal file
BIN
utilities/images/lgrey064.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
59
utilities/launchMig.php
Normal file
59
utilities/launchMig.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* launchMig.php -- help script
|
||||
*
|
||||
* This program is called from the: migrateData.php application as an AJAX event - the sole purpose of this script
|
||||
* is to unpack the POST data from the AJAX request, and build a migration-request event broker payload.
|
||||
*
|
||||
* Next, we instantiate a new broker client to the migration broker and publish the migration event request - the
|
||||
* output from the script is in the broker payload returned by the migration broker -- if all was successful, we'll
|
||||
* output (for formatted display) the migration report -- else, we'll display the diagnostic messages.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-04-18 mks DB-43: original coding
|
||||
*
|
||||
*/
|
||||
// if this page was not called by AJAX, die
|
||||
if (!$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') die('Invalid request');
|
||||
|
||||
// get variables sent from client-side page
|
||||
$data = isset($_POST['d']) ? (json_decode(strip_tags($_POST['d']), true)) : null;
|
||||
$meta = isset($_POST['m']) ? (json_decode(strip_tags($_POST['m']), true)): null;
|
||||
|
||||
// output an error message if the required arrays weren't posted to the form
|
||||
if (is_null($data)) {
|
||||
echo ERROR_DATA_404 . $eos;
|
||||
exit;
|
||||
}
|
||||
if (is_null($meta)) {
|
||||
echo ERROR_DATA_META_404 . $eos;
|
||||
exit;
|
||||
}
|
||||
|
||||
// load namaste-light
|
||||
try {
|
||||
require_once(dirname(__DIR__) . '/config/sneakerstrap.inc');
|
||||
} catch (ParseError | Throwable $p) {
|
||||
$errorList[] = ERROR_TYPE_EXCEPTION_PARSE . $p->getMessage();
|
||||
}
|
||||
|
||||
// todo: validate that the current Namaste config has a migration broker running...
|
||||
$objMig = new gacBrokerClient(BROKER_QUEUE_M, basename(__FILE__));
|
||||
if (!$objMig->status) {
|
||||
echo ERROR_TEMPLATE_INSTANTIATE . BROKER_QUEUE_M . $eos;
|
||||
}else {
|
||||
$brokerPayload = [BROKER_REQUEST => BROKER_REQUEST_MIGRATION, BROKER_DATA => $data, BROKER_META_DATA => $meta];
|
||||
$result = $objMig->call(gzcompress(json_encode($brokerPayload)));
|
||||
$result = json_decode(gzuncompress($result), true);
|
||||
if ($result[PAYLOAD_STATE] == true)
|
||||
var_export($result[PAYLOAD_RESULTS]);
|
||||
else
|
||||
var_export($result[PAYLOAD_DIAGNOSTICS]);
|
||||
}
|
||||
if (is_object($objMig)) $objMig->__destruct();
|
||||
unset($objMig);
|
||||
193
utilities/logger.css
Normal file
193
utilities/logger.css
Normal file
@@ -0,0 +1,193 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #AAA url('./images/lgrey064.jpg') repeat top left scroll;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: verdanna, arial, sans-serif;
|
||||
}
|
||||
|
||||
div.title {
|
||||
margin: 0;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
font-size: 20px;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
div.container {
|
||||
border: 1px solid black;
|
||||
margin: 0;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: url('./images/lblue047.gif') repeat;
|
||||
box-shadow: 3px 3px 4px #000;
|
||||
}
|
||||
|
||||
div.rowMeta {
|
||||
margin: 0;
|
||||
width: 900px;
|
||||
padding-left: 10px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #006400;
|
||||
}
|
||||
|
||||
div.rowData {
|
||||
margin: 0;
|
||||
padding-left: 25px;
|
||||
width: 900px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.rowText {
|
||||
margin : 0;
|
||||
padding-left: 25px;
|
||||
width: 900px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.rowTextGray {
|
||||
margin : 0;
|
||||
padding-left: 25px;
|
||||
width: 900px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
div.rowHist {
|
||||
margin: 0;
|
||||
padding-left: 50px;
|
||||
width: 900px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.gray {
|
||||
color : gray;
|
||||
}
|
||||
span.green {
|
||||
color : green;
|
||||
}
|
||||
span.red {
|
||||
color : red;
|
||||
}
|
||||
|
||||
.required {
|
||||
color : red;
|
||||
font-size: xx-small;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.rowSuccess {
|
||||
margin : 0;
|
||||
padding-left: 30px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color : green;
|
||||
}
|
||||
|
||||
div.rowError {
|
||||
margin: 0;
|
||||
padding-left: 30px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
a.delete {
|
||||
background-image: url('./images/delete-icon.png');
|
||||
background-repeat:no-repeat;
|
||||
background-size: 16px auto;
|
||||
display:inline-block;
|
||||
position:absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
/*cursor: pointer;*/
|
||||
}
|
||||
|
||||
a.cachekey {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
span.highlight {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
.buttonCenter {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.omeSubmit {
|
||||
-moz-box-shadow:inset 0px 1px 0px 0px #bbdaf7;
|
||||
-webkit-box-shadow:inset 0px 1px 0px 0px #bbdaf7;
|
||||
box-shadow:inset 0px 1px 0px 0px #bbdaf7;
|
||||
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #79bbff), color-stop(1, #378de5) );
|
||||
background:-moz-linear-gradient( center top, #79bbff 5%, #378de5 100% );
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#79bbff', endColorstr='#378de5');
|
||||
background-color:#79bbff;
|
||||
-webkit-border-top-left-radius:20px;
|
||||
-moz-border-radius-topleft:20px;
|
||||
border-top-left-radius:20px;
|
||||
-webkit-border-top-right-radius:0px;
|
||||
-moz-border-radius-topright:0px;
|
||||
border-top-right-radius:0px;
|
||||
-webkit-border-bottom-right-radius:20px;
|
||||
-moz-border-radius-bottomright:20px;
|
||||
border-bottom-right-radius:20px;
|
||||
-webkit-border-bottom-left-radius:0px;
|
||||
-moz-border-radius-bottomleft:0px;
|
||||
border-bottom-left-radius:0px;
|
||||
text-indent:0;
|
||||
border:1px solid #84bbf3;
|
||||
display:inline-block;
|
||||
color:#ffffff;
|
||||
font-family:Arial;
|
||||
font-size:15px;
|
||||
font-weight:bold;
|
||||
font-style:normal;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
width:100px;
|
||||
text-decoration:none;
|
||||
text-align:center;
|
||||
text-shadow:1px 1px 0px #528ecc;
|
||||
}
|
||||
.omeSubmit:hover {
|
||||
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #378de5), color-stop(1, #79bbff) );
|
||||
background:-moz-linear-gradient( center top, #378de5 5%, #79bbff 100% );
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#378de5', endColorstr='#79bbff');
|
||||
background-color:#378de5;
|
||||
}.omeSubmit:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
1590
utilities/migrateData.php
Normal file
1590
utilities/migrateData.php
Normal file
File diff suppressed because it is too large
Load Diff
357
utilities/mongoConfig.php
Normal file
357
utilities/mongoConfig.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php /** @noinspection PhpComposerExtensionStubsInspection */
|
||||
/**
|
||||
* mongoConfig -- utility script
|
||||
*
|
||||
* mongoConfig is a utility script that updates the existing indexes in all mongo collections in the database.
|
||||
*
|
||||
* this program should be run whenever new templates are added to the source tree, or when an existing template
|
||||
* is edited. Actually, the program should just be run whenever the source is pushed to a new environment.
|
||||
*
|
||||
* the script reads all of the files in the ./classes/templates directory and every template file is parsed. If
|
||||
* the template has been configured for a mongo schema, then it's indexing information is scraped.
|
||||
*
|
||||
* Processing generally follows the formula of:
|
||||
*
|
||||
* -- process all the compound indexes first
|
||||
* -- process all the other indexes individually
|
||||
* -- process individual index options (unique, sparse, ttl)
|
||||
*
|
||||
* NOTES:
|
||||
* ------
|
||||
* this program writes it's output to ./logs/mongoConfig.log
|
||||
* The createIndex() method only creates an index if an index of the same specification does not already exist.
|
||||
*
|
||||
* -- start version control in the template files and add the version number in to the index name, set in options
|
||||
* -- push re-indexing into the background with the option background:true (sub-optimal)
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-03-17 mks CORE-467: original coding
|
||||
* 02-07-19 mks DB-115: fixed index processing
|
||||
* 05-21-19 mks DB-116: updated index processing to be specific to each named service environment
|
||||
* 10-22-19 mks DB-136: removed assumption that mongo will always be under RBAC allowing unsecured logins
|
||||
* Fixed error in $outfile processing where the parent directory is missing
|
||||
*
|
||||
*/
|
||||
$_REDIRECT=false; // enable stdout
|
||||
require_once(dirname(__DIR__) . '/config/sneakerstrap.inc'); // load env
|
||||
$errors = null;
|
||||
$res = 'MDBC: ';
|
||||
$envList = null;
|
||||
|
||||
// get the database configuration
|
||||
$dbConfig = gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_MONGODB];
|
||||
|
||||
// break out of the script if mongo isn't enabled
|
||||
if (isset($dbConfig[CONFIG_DATABASE_MONGODB_ENABLED]) and $dbConfig[CONFIG_DATABASE_MONGODB_ENABLED] != 1) {
|
||||
exit(ERROR_MDB_NOT_ENABLED);
|
||||
}
|
||||
|
||||
// generate a list of environments this currently-running script can "see"
|
||||
foreach (gasConfig::$settings[CONFIG_REGISTERED_SERVICES] as $service => $enabled)
|
||||
if (gasConfig::$settings[$service][CONFIG_IS_LOCAL] and gasConfig::$settings[$service][CONFIG_ACTIVE])
|
||||
$envList[] = $service;
|
||||
|
||||
$logFile = dirname(__DIR__) . DIR_LOGS . FILE_MONGO_CONFIG_LOG;
|
||||
$outFile = dirname(__DIR__) . DIR_SCRIPTS . DIR_MONGO . FILE_MONGO_INDEX_SCRIPT;
|
||||
if (!file_exists($logFile)) touch($logFile);
|
||||
if (!file_exists($outFile)) {
|
||||
if (!touch($outFile)) {
|
||||
$hdr = basename(__FILE__) . AT . __LINE__ . COLON;
|
||||
$msg = ERROR_OPEN_LOG_FILE . $outFile;
|
||||
consoleLog($res, CON_ERROR, $hdr . $msg);
|
||||
consoleLog($res, CON_ERROR, INFO_NO_DIR);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$pLogFile = @fopen($logFile, 'a');
|
||||
$pIndexFile = @fopen($outFile, 'w');
|
||||
|
||||
if (false === $pLogFile) {
|
||||
echo ERROR_OPEN_LOG_FILE . $logFile . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
if (false === $pIndexFile) {
|
||||
echo ERROR_OPEN_LOG_FILE . $outFile . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@fwrite($pLogFile, getDateTime() . CON_SUCCESS . $res . 'begin processing templates' . PHP_EOL);
|
||||
@fwrite($pLogFile, getDateTime() . CON_SUCCESS . $res . 'opened output file: ' . $outFile . PHP_EOL);
|
||||
@fwrite($pIndexFile, '#! /bin/sh' . PHP_EOL);
|
||||
|
||||
// pull a copy of the config into memory
|
||||
$config = gasConfig::$settings[CONFIG_DATABASE][CONFIG_DATABASE_MONGODB];
|
||||
$firstPass = true;
|
||||
|
||||
// loop through each Namaste-supported environment...
|
||||
foreach ($envList as $environment) {
|
||||
@fwrite($pIndexFile, '# Processing Environment: ' . $environment . PHP_EOL);
|
||||
// reset RBAC credentials
|
||||
$user = '';
|
||||
$password = '';
|
||||
$authDB = '';
|
||||
$indexText = null;
|
||||
// if the current env is set and if that env has enabled mongoDB then...
|
||||
if (array_key_exists($environment, $config) and intval($config[$environment][STRING_ENABLED]) === 1) {
|
||||
// derive port assignment based-off the current db configuration (shard v. replSet v. standAlone)
|
||||
if (intval($config[$environment][CONFIG_DATABASE_MONGODB_SHARDING][CONFIG_DATABASE_MONGODB_ENABLED]) === 1) {
|
||||
$port = $config[$environment][CONFIG_DATABASE_MONGODB_SHARDING][CONFIG_DATABASE_MONGODB_SHARDING_MONGOS_NODES][CONFIG_DATABASE_MONGODB_ADMIN_REPLSET_SET];
|
||||
$port = intval(substr($port, -5));
|
||||
} elseif (intval($config[$environment][CONFIG_DATABASE_MONGODB_REPLSET][CONFIG_DATABASE_MONGODB_REPLSET_ENABLED]) === 1) {
|
||||
$port = $config[$environment][CONFIG_DATABASE_MONGODB_REPLSET][CONFIG_DATABASE_MONGODB_REPLSET_DSN][CONFIG_DATABASE_MONGODB_ADMIN_REPLSET_SET][0];
|
||||
$port = intval(substr($port, -5));
|
||||
} else {
|
||||
$port = intval($config[$environment][CONFIG_DATABASE_MONGODB_PORT]);
|
||||
}
|
||||
// if RBAC is enabled, grabbed the login credentials from the current env
|
||||
if ($config[$environment][CONFIG_DATABASE_MONGODB_USE_AUTH] == 1) {
|
||||
$user = $config[$environment][CONFIG_DATABASE_MONGODB_USER];
|
||||
$password = $config[$environment][CONFIG_DATABASE_MONGODB_PASSWORD];
|
||||
$authDB = gasConfig::$settings[CONFIG_ID][CONFIG_ID_ENV] . UDASH . $config[$environment][CONFIG_DATABASE_MONGODB_AUTH_SOURCE];
|
||||
$command = 'mongo -u ' . $user . ' -p ' . $password . ' --port ' . $port . ' --authenticationDatabase ' . $authDB;
|
||||
} else {
|
||||
$command = 'mongo --port ' . $port;
|
||||
}
|
||||
|
||||
/** @noinspection PhpComposerExtensionStubsInspection */
|
||||
/** @var MongoClient $mongoResource */
|
||||
$mongoResource = gasResourceManager::fetchResource(RESOURCE_MONGO_MASTER, $environment);
|
||||
|
||||
if (is_null($mongoResource)) {
|
||||
@fwrite($pLogFile, getDateTime() . CON_ERROR . $res . ERROR_MONGO_CONNECT . AT . $environment . PHP_EOL);
|
||||
fclose($pLogFile);
|
||||
fclose($pIndexFile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// STEP 1 -- for every c-type class template, load and process the template
|
||||
foreach(glob(dirname(getcwd()) . DIR_CLASSES . DIR_TEMPLATE . '/*' . STRING_CLASS_FILE_EXT) as $filename) {
|
||||
$currentClass = basename($filename);
|
||||
$currentClass = preg_replace("/" . STRING_CLASS_FILE_EXT . "/", "", $currentClass);
|
||||
// extract the $tlti from the front of the template for the factory-class instantiation
|
||||
$tlti = substr($currentClass, 0, 3);
|
||||
$currentClass = preg_replace("/" . $tlti . "/", "", $currentClass);
|
||||
$database = null;
|
||||
$collection = null;
|
||||
$collectionName = null;
|
||||
|
||||
if ($currentClass == 'SystemData' and $environment == ENV_ADMIN)
|
||||
$x = 1;
|
||||
|
||||
echo 'processing: ' . $currentClass . '...' . $eos;
|
||||
try {
|
||||
$e = array();
|
||||
$meta = [ META_TEMPLATE => $currentClass, META_CLIENT => CLIENT_SYSTEM, META_TLTI => $tlti ];
|
||||
$objFactory = new gacFactory($meta, FACTORY_EVENT_NEW_CLASS, '', $e);
|
||||
if (is_null($objFactory)) break; // we couldn't instantiate the factory class for this template
|
||||
// do not process PDO scripts
|
||||
if ($objFactory->template->schema == TEMPLATE_DB_PDO) {
|
||||
$objFactory->__destruct();
|
||||
unset($objFactory);
|
||||
continue;
|
||||
}
|
||||
// do not process if the template is not a member of the current environment
|
||||
if ($objFactory->template->service != $environment) {
|
||||
$objFactory->__destruct();
|
||||
unset($objFactory);
|
||||
continue;
|
||||
}
|
||||
$version = $objFactory->template->version;
|
||||
$ext = $objFactory->template->extension;
|
||||
$service = $objFactory->template->service;
|
||||
$collectionName = $objFactory->template->collection;
|
||||
/** @var gacMongoDB $tmpObj */
|
||||
$tmpObj = $objFactory->widget;
|
||||
$collectionName = $tmpObj->getCollectionName();
|
||||
$dbName = $tmpObj->getDBName();
|
||||
if (is_object($objFactory)) $objFactory->__destruct();
|
||||
unset($objFactory);
|
||||
} catch (Throwable $t) {
|
||||
fclose($pLogFile);
|
||||
fclose($pIndexFile);
|
||||
exit($t->getMessage() . $eos);
|
||||
}
|
||||
|
||||
$indexes = array(); // this is the index payload we'll submit to the mongoDB Manager\Command
|
||||
$options = array(); // this is the options payload for the corresponding index
|
||||
$commands = array(); // this is the list of commands that comprise the final ouput
|
||||
|
||||
// indexes
|
||||
$singleIndices = $tmpObj->singleIndexes;
|
||||
$compoundIndices = $tmpObj->compoundIndexes;
|
||||
$multiKeyIndices = $tmpObj->multiKey;
|
||||
// index properties
|
||||
$uniqueIndices = $tmpObj->uniqueIndexes;
|
||||
$partialIndices = $tmpObj->partialIndexes;
|
||||
$t2LiveIndices = $tmpObj->ttlIndexes;
|
||||
|
||||
// all indexing done in the background
|
||||
$sysOption = [
|
||||
MONGO_STRING_BACKGROUND => true
|
||||
];
|
||||
|
||||
// order for these two variables is critical: do *NOT* add or delete from one unless you do it to the other
|
||||
// while maintaining identical positions for each index type in the arrays. If we ever support indexes
|
||||
// other than what appears in these lists, we'll have not only manually add them to the lists, but also
|
||||
// code the respective validation and processing bits too.
|
||||
$indexTypes = [
|
||||
$partialIndices, $uniqueIndices, $t2LiveIndices,
|
||||
$singleIndices, $compoundIndices, $multiKeyIndices
|
||||
];
|
||||
$indexList = [
|
||||
'partialIndices' => 0, 'uniqueIndices' => 1, 't2LiveIndices' => 2,
|
||||
'singleIndices' => 3, 'compoundIndices' => 4, 'multiKeyIndices' => 5
|
||||
];
|
||||
|
||||
// process partial index properties for the class first
|
||||
$count = 0;
|
||||
foreach ($indexList as $indexName => $indexCounter) {
|
||||
if (!empty($indexTypes[$indexCounter])) {
|
||||
$badIndexName = false;
|
||||
$indexText[][MONGO_COLLECTION_NAME] = $collectionName;
|
||||
// the first part of this is to validate the index column/label names as valid/declared indexes
|
||||
foreach ($indexTypes[$indexCounter] as $indexLabel => $indexContents) {
|
||||
// strip, if it exists, the extension of the column name so we can grep it in our index lists
|
||||
$modifiedField = ($indexName == STRING_PARTIAL_INDICES) ?
|
||||
preg_replace("/" . $ext . "/", "", key($indexContents[0]))
|
||||
:
|
||||
preg_replace("/" . $ext . "/", "", $indexLabel);
|
||||
if (!in_array($modifiedField, $tmpObj->indexList)) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__FILE__), __LINE__);
|
||||
$msg = sprintf(ERROR_MDB_INDEX_UNDECL, array_search($indexCounter, $indexList), basename($filename), $modifiedField);
|
||||
echo $hdr . $msg . PHP_EOL;
|
||||
$badIndexName = true;
|
||||
}
|
||||
// if we have one, just one, bad index reference, we need to error-out and stop processing
|
||||
// (but we'll echo a list of the bad index names before exiting)
|
||||
if ($badIndexName) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__FILE__), __LINE__);
|
||||
echo $hdr . ERROR_DATA_VALIDATION;
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* the $indexes and $options structure contain all elements of the current index. If an index,
|
||||
* or index property, does not have options, then the placeholder for that position in $options
|
||||
* will be set to null.
|
||||
*
|
||||
*/
|
||||
switch ($indexCounter) {
|
||||
// changed structure of $indexes/$options to down-layer the data that will be passed to
|
||||
// mongo so as to avoid index name collisions within the arrays using the column name.
|
||||
//
|
||||
// the goal of this section is to generate the structures that we'll convert to json-
|
||||
// -encoded arrays that will ultimately be written to the bash deployment script
|
||||
case 0 :
|
||||
// partial indexes (done)
|
||||
for ($index = 0, $max = count($indexContents[0]); $index < $max; $index++)
|
||||
$indexes[][key($indexContents[$index])] = $indexContents[$index][key($indexContents[$index])];
|
||||
$options[][ MONGO_STRING_PARTIAL_FE ] = $indexContents[1][0];
|
||||
break;
|
||||
case 1 :
|
||||
// unique index (done)
|
||||
$indexes[][$indexLabel] = $uniqueIndices[$indexLabel];
|
||||
$options[][MONGO_STRING_UNIQUE] = true;
|
||||
break;
|
||||
case 2 :
|
||||
// time-to-live indexes
|
||||
$indexes[][$indexLabel] = 1;
|
||||
$options[] = [ MONGO_STRING_EXPIRE_SEC => $t2LiveIndices[$indexLabel] ];
|
||||
break;
|
||||
case 3 :
|
||||
// single indexes (done)
|
||||
$indexes[][$indexLabel] = $singleIndices[$indexLabel];
|
||||
break;
|
||||
case 4 :
|
||||
// compound indexes (done)
|
||||
// mongo imposes a limit of 32 fields on compound indexes
|
||||
// mongo does not use index labels (that's a mysql thing) but we do use the label to
|
||||
// distinguish/differentiate the index lists
|
||||
$indexes[][$indexLabel] = $indexContents;
|
||||
break;
|
||||
case 5 :
|
||||
// multikey indexes
|
||||
for ($index = 0, $max = count($multiKeyIndices); $index < $max; $index++)
|
||||
$indexes[][$indexLabel] = $multiKeyIndices[$indexLabel];
|
||||
break;
|
||||
default :
|
||||
// unknown index type
|
||||
$hdr = sprintf(INFO_LOC, __FILE__, __LINE__);
|
||||
$msg = $hdr . ERROR_MDB_UNK_IDX_TYPE . $indexLabel;
|
||||
echo $msg;
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// the second part of this is to generate the BSON for each index type outputting the directives
|
||||
// to a bash-script that will be executed (manually) after this script completes processing
|
||||
switch ($indexCounter) {
|
||||
case 0 :
|
||||
// partial indexes
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode($indexes[$index]) . COMMA . json_encode($options[$index]);
|
||||
break;
|
||||
case 1 :
|
||||
// unique indexes (done)
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode($indexes[$index]) . COMMA . json_encode($options[$index]);
|
||||
break;
|
||||
case 2 :
|
||||
// t2Live indexes
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode([$indexes[$index], $options[$index]]);
|
||||
break;
|
||||
case 3 :
|
||||
// single indexes (done)
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode($indexes[$index]);
|
||||
break;
|
||||
case 4 :
|
||||
// compound indexes (done)
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode($indexes[$index][key($indexes[$index])]);
|
||||
break;
|
||||
case 5 :
|
||||
// multi-key indexes
|
||||
for ($index = 0, $max = count($indexes); $index < $max; $index++)
|
||||
$indexText[] = json_encode($indexes[$index][key($indexes[$index])]);
|
||||
break;
|
||||
default :
|
||||
// unknown index type
|
||||
$hdr = sprintf(INFO_LOC, __FILE__, __LINE__);
|
||||
$msg = $hdr . ERROR_MDB_UNK_IDX_TYPE . $indexLabel;
|
||||
echo $msg;
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
unset($indexes, $options); // reset the processed-index/options containers
|
||||
}
|
||||
}
|
||||
} // close the env-enabled loop
|
||||
if (!empty($indexText)) {
|
||||
// we have generated indexing commands --- write out the command to log into mongo
|
||||
@fwrite($pIndexFile, $command . ' << EOF' . PHP_EOL);
|
||||
@fwrite($pIndexFile, 'use ' . $dbName . PHP_EOL);
|
||||
for ($index = 0, $max = count($indexText); $index < $max; $index++) {
|
||||
if (is_array($indexText[$index])) {
|
||||
$collectionName = $indexText[$index][MONGO_COLLECTION_NAME];
|
||||
continue;
|
||||
}
|
||||
@fwrite($pIndexFile, 'db.' . $collectionName . '.createIndex(' . $indexText[$index] . ')' . PHP_EOL);
|
||||
}
|
||||
@fwrite($pIndexFile, 'EOF' . PHP_EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@fwrite($pLogFile, getDateTime() . CON_SUCCESS . $res . basename(__FILE__) . ': script processing ends' . PHP_EOL);
|
||||
fclose($pLogFile);
|
||||
fclose($pIndexFile);
|
||||
chmod($outFile, 0755);
|
||||
echo 'processing ended successfully!' . PHP_EOL;
|
||||
exit(0);
|
||||
1063
utilities/mysqlConfig.php
Normal file
1063
utilities/mysqlConfig.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user