Skip to content

Instantly share code, notes, and snippets.

@alexweissman
Last active August 29, 2015 14:10
Show Gist options
  • Save alexweissman/e115464a5930b7988e0e to your computer and use it in GitHub Desktop.
Save alexweissman/e115464a5930b7988e0e to your computer and use it in GitHub Desktop.
Custom class for rendering counters with UserFrosting
<?php
require_once("template_functions.php");
class CounterBuilder {
/* Information about the counters to render.
* Allowed options:
* 'label'
* 'display': 'hidden', 'show'
* 'type': 'quantity', 'rate', 'currency'
* 'icon'
* 'preprocess' : a function to call to process the value before rendering.
* 'default' : the default value to use if a value is not specified
*/
protected $_counters = array();
protected $_data = array();
protected $_template = "";
public function __construct($template, $counters = array(), $data = array()) {
$this->_counters = $counters;
$this->_data = $data;
$this->_template = $template;
}
public function render(){
$result = $this->_template;
$rendered_counters = array();
// Render counters
foreach ($this->_counters as $counter_name => $counter){
$type = isset($counter['type']) ? $counter['type'] : "text";
if ($type == "quantity"){
$rendered_counters[$counter_name] = $this->renderQuantityCounter($counter_name);
} else if ($type == "rate"){
$rendered_counters[$counter_name] = $this->renderRateCounter($counter_name);
} else if ($type == "currency"){
$rendered_counters[$counter_name] = $this->renderCurrencyCounter($counter_name);
}
}
return replaceKeyHooks($rendered_counters, $result);
}
// Renders a quantity counter with the specified name.
private function renderQuantityCounter($counter_name){
$counter_data = $this->generateFieldData($counter_name);
$result = "
<div class='panel panel-{{style}}'>
<div class='panel-heading'>
<div class='row'>
<div class='col-xs-4'>
<i class='{{icon}} fa-5x'></i>
</div>
<div class='col-xs-8 text-right'>
<p class='announcement-heading'>{{value}}</p>
<p class='announcement-text'>{{label}}</p>
</div>
</div>
</div>
</div>";
return replaceKeyHooks($counter_data, $result);
}
// Renders a rate counter with the specified name.
private function renderRateCounter($counter_name){
$counter_data = $this->generateFieldData($counter_name);
$result = "
<div class='panel panel-{{style}}'>
<div class='panel-heading'>
<div class='row'>
<div class='col-xs-4'>
<i class='fa fa-usd fa-5x'></i>
</div>
<div class='col-xs-8 text-right'>
<p class='announcement-heading'>{{value}}/hr</p>
<p class='announcement-text'>{{label}}</p>
</div>
</div>
</div>
</div>";
return replaceKeyHooks($counter_data, $result);
}
// Renders a currency counter with the specified name.
private function renderCurrencyCounter($counter_name){
$counter_data = $this->generateFieldData($counter_name);
$counter = $this->_counters[$counter_name];
$counter_data['neg_label'] = isset($counter['neg_label']) ? $counter['neg_label'] : "they owe us";
$counter_data['neg_style'] = isset($counter['neg_style']) ? $counter['neg_style'] : "danger";
$counter_data['neutral_label'] = isset($counter['neutral_label']) ? $counter['neutral_label'] : "settled up";
$counter_data['neutral_style'] = isset($counter['neutral_style']) ? $counter['neutral_style'] : "info";
$counter_data['pos_label'] = isset($counter['pos_label']) ? $counter['pos_label'] : "we owe them";
$counter_data['pos_style'] = isset($counter['pos_style']) ? $counter['pos_style'] : "success";
if ($counter_data['value'] < 0) {
$counter_data['label'] = $counter_data['neg_label'];
$counter_data['style'] = $counter_data['neg_style'];
} else if ($counter_data['value'] == 0) {
$counter_data['label'] = $counter_data['neutral_label'];
$counter_data['style'] = $counter_data['neutral_style'];
} else {
$counter_data['label'] = $counter_data['pos_label'];
$counter_data['style'] = $counter_data['pos_style'];
}
$result = "
<div class='panel panel-{{style}}'>
<div class='panel-heading'>
<div class='row'>
<div class='col-xs-4'>
<i class='{{icon}} fa-5x'></i>
</div>
<div class='col-xs-8 text-right'>
<p class='announcement-heading'>\${{value}}</p>
<p class='announcement-text'>{{label}}</p>
</div>
</div>
</div>
</div>";
return replaceKeyHooks($counter_data, $result);
}
private function generateFieldData($counter_name){
$counter = $this->_counters[$counter_name];
$counter_data = array();
$counter_data['name'] = $counter_name;
$counter_data['label'] = isset($counter['label']) ? $counter['label'] : null;
$counter_data['style'] = isset($counter['style']) ? $counter['style'] : "info";
$counter_data['icon'] = isset($counter['icon']) ? $counter['icon'] : "fa fa-calculator";
if (isset($this->_data[$counter_name]))
$counter_data['value'] = $this->_data[$counter_name];
else {
// Set default value
if (isset($counter['default'])){
$counter_data['value'] = $counter['default'];
} else {
$counter_data['value'] = "";
}
}
// Preprocess value
if (isset($counter['preprocess'])){
$method = new ReflectionFunction($counter['preprocess']);
if ($method){
$counter_data['value'] = $method->invokeArgs(array($counter_data['value']));
}
}
return $counter_data;
}
}
?>
// Display tutor counter widgets
function tutorCounterWidgets(box_id, tutor_id) {
// Generate the form
$.ajax({
type: "GET",
url: FORMSPATH + "counters_tutor.php",
data: {
box_id: box_id,
tutor_id: tutor_id,
ajaxMode: true
},
dataType: 'json',
cache: false
})
.fail(function(result) {
addAlert("danger", "Oops, looks like our server might have goofed. If you're an admin, please check the PHP error logs.");
alertWidget('display-alerts');
})
.done(function(result) {
$('#' + box_id).html(result['data']);
});
}
<?php
require_once("../models/config.php");
// Request method: GET
$ajax = checkRequestMode("get");
if (!securePage(__FILE__)){
// Forward to index page
addAlert("danger", "Whoops, looks like you don't have permission to view that page.");
apiReturnError($ajax, ACCOUNT_ROOT);
}
// Sanitize input data
$get = filter_input_array(INPUT_GET, FILTER_SANITIZE_SPECIAL_CHARS);
// Parameters: box_id, tutor_id
// box_id: the desired name of the div that will contain the widget.
// tutor_id: the id of the tutor
// Set up Valitron validator
$v = new Valitron\DefaultValidator($get);
$v->rule('required', 'box_id');
$v->rule('required', 'tutor_id');
$v->rule('integer', 'tutor_id');
// Validate!
$v->validate();
// Process errors
if (count($v->errors()) > 0) {
foreach ($v->errors() as $idx => $error){
addAlert("danger", $error);
}
apiReturnError($ajax, ACCOUNT_ROOT);
} else {
$get = $v->data();
}
$template = "
<div id='{$get['box_id']}' class='row'>
<div class='col-md-3'>
{{balance}}
</div>
<div class='col-md-3'>
{{sessions_week}}
</div>
<div class='col-md-3'>
{{sessions_semester}}
</div>
<div class='col-md-3'>
{{students_count}}
</div>
";
// Load the tutor and determine counter parameters
$tutor = loadTutor($get['tutor_id']);
// Add up tutor completed sessions for this semester
$semester_start_date = $loggedInUser->semester['start_date'];
$semester_end_date = $loggedInUser->semester['end_date'];
$status = ['CP'];
if (($sessions = loadTutorSessions($get['tutor_id'], $status, $semester_start_date, $semester_end_date)) === false ){
apiReturnError($ajax, ACCOUNT_ROOT);
}
$sessions_semester = 0;
if ($sessions){
foreach($sessions as $session){
$sessions_semester += $session['duration'];
}
} else {
$sessions_semester = 0;
}
// Add up tutor completed sessions for this week
$week_start_date = date('Y-m-d H:i:s', strtotime("last Saturday"));
$week_end_date = date('Y-m-d H:i:s', strtotime("next Saturday"));
if (($sessions = loadTutorSessions($get['tutor_id'], $status, $week_start_date, $week_end_date)) === false ){
apiReturnError($ajax, ACCOUNT_ROOT);
}
$sessions_week = 0;
if ($sessions){
foreach($sessions as $session){
$sessions_week += $session['duration'];
}
} else {
$sessions_week = 0;
}
$counters = [
'balance' => [
'type' => 'currency',
'icon' => 'fa fa-money',
'neg_label' => "tutor has extra cash",
'neg_style' => "success",
'neutral_label' => "paid in full",
'pos_label' => "we owe the tutor",
'pos_style' => "danger",
'preprocess' => "formatCurrency"
],
'sessions_week' => [
'type' => 'quantity',
'label' => "hours completed this week",
'icon' => "fa fa-clock-o",
'style' => "info"
],
'sessions_semester' => [
'type' => 'quantity',
'label' => "hours completed in " . $loggedInUser->semester['name'],
'icon' => "fa fa-clock-o",
'style' => "info"
],
'students_count' => [
'type' => 'quantity',
'label' => "active students " . $loggedInUser->semester['name'],
'icon' => "fa fa-clock-o",
'style' => "warning"
],
];
$data = [
'balance' => $tutor['balance'],
'sessions_semester' => $sessions_semester,
'sessions_week' => $sessions_week,
'students_count' => $tutor['count_students']
];
$cb = new CounterBuilder($template, $counters, $data);
$response = $cb->render();
if ($ajax)
echo json_encode(array("data" => $response), JSON_FORCE_OBJECT);
else
echo $response;
?>
<div id="widget-count-boxes">
</div>
<script>
tutorCounterWidgets('widget-count-boxes', selected_user_id);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment