Badges WIP: Rules autoloading work
This commit is contained in:
parent
692c530fb6
commit
0f3e73cbfa
@ -2,7 +2,7 @@
|
||||
/* Copyright 2013 Zachary Doll */
|
||||
|
||||
/**
|
||||
* All is the base class for controllers throughout the gamification applicati0n.
|
||||
* Contains management code for creating badges.
|
||||
*
|
||||
* @since 1.0
|
||||
* @package Yaga
|
||||
@ -51,6 +51,26 @@ class BadgesController extends DashboardController {
|
||||
|
||||
$this->Render();
|
||||
}
|
||||
|
||||
public function UpdateRuleMap() {
|
||||
foreach(glob(PATH_APPLICATIONS . DS . 'yaga' . DS . 'rules' . DS . '*.php') as $filename) {
|
||||
include_once $filename;
|
||||
}
|
||||
$Cache = array();
|
||||
$Cache['Class'] = array();
|
||||
$Cache['Name'] = array();
|
||||
$Cache['Description'] = array();
|
||||
|
||||
foreach(get_declared_classes() as $className) {
|
||||
if(in_array('YagaRule', class_implements($className))) {
|
||||
$object = new $className();
|
||||
$Cache['Name'][] = $object->FriendlyName();
|
||||
$Cache['Description'][] = $object->Description();
|
||||
$Cache['Class'][] = $className;
|
||||
}
|
||||
}
|
||||
decho($Cache);
|
||||
}
|
||||
|
||||
public function Edit($BadgeID = NULL) {
|
||||
$this->Permission('Yaga.Badges.Manage');
|
||||
@ -65,50 +85,32 @@ class BadgesController extends DashboardController {
|
||||
}
|
||||
|
||||
if($this->Form->IsPostBack() == FALSE) {
|
||||
$this->Form->SetData($this->Badge);
|
||||
if(property_exists($this, 'Badge')) {
|
||||
$this->Form->SetData($this->Badge);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$Upload = new Gdn_Upload();
|
||||
$TmpImage = $Upload->ValidateUpload('PhotoUpload', FALSE);
|
||||
|
||||
if($TmpImage) {
|
||||
// Generate the target image name
|
||||
$TargetImage = $Upload->GenerateTargetName(PATH_UPLOADS);
|
||||
$ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
|
||||
|
||||
// Save the uploaded image
|
||||
$Parts = $Upload->SaveAs($TmpImage, $ImageBaseName);
|
||||
|
||||
$this->Form->SetFormValue('Photo', $Parts['SaveName']);
|
||||
}
|
||||
if($this->Form->Save()) {
|
||||
$Upload = new Gdn_Upload();
|
||||
$TmpImage = $Upload->ValidateUpload('PhotoUpload_New', FALSE);
|
||||
|
||||
if($TmpImage) {
|
||||
// Generate the target image name
|
||||
$TargetImage = $Upload->GenerateTargetName(PATH_UPLOADS);
|
||||
$ImageBaseName = pathinfo($TargetImage, PATHINFO_BASENAME);
|
||||
|
||||
// Save the uploaded image
|
||||
$Parts = $Upload->SaveAs(
|
||||
$TmpImage, $ImageBaseName
|
||||
);
|
||||
$this->Form->SetFormValue('Photo', $Parts['SaveName']);
|
||||
}
|
||||
|
||||
if($Edit) {
|
||||
$Badge = $this->BadgeModel->GetBadge($this->Form->GetFormValue('BadgeID'));
|
||||
}
|
||||
else {
|
||||
$Badge = $this->BadgeModel->GetNewestBadge();
|
||||
}
|
||||
$NewBadgeRow = '<tr id="BadgeID_' . $Badge->BadgeID . '" data-badgeid="' . $Badge->BadgeID . '"' . ($Alt ? ' class="Alt"' : '') . '>';
|
||||
$NewBadgeRow .= '<td>' . Img($Badge->Photo) . '</td>';
|
||||
$NewBadgeRow .= "<td>$Badge->Name</td>";
|
||||
$NewBadgeRow .= "<td>$Badge->Description</td>";
|
||||
$NewBadgeRow .= "<td>$Badge->RuleClass</td>";
|
||||
$NewBadgeRow .= "<td>$Badge->RuleCriteria</td>";
|
||||
$NewBadgeRow .= "<td>$Badge->AwardValue</td>";
|
||||
$ToggleText = ($Badge->Enabled) ? T('Yes') : T('No');
|
||||
$NewBadgeRow .= '<td>' . Anchor($ToggleText, 'yaga/badges/toggle/' . $Badge->BadgeID, array('class' => 'Hijack')) . '</td>';
|
||||
$NewBadgeRow .= '<td>' . Anchor(T('Edit'), 'yaga/badges/edit/' . $Badge->BadgeID, array('class' => 'SmallButton')) . Anchor(T('Delete'), 'yaga/badges/delete/' . $Badge->BadgeID, array('class' => 'Danger PopConfirm SmallButton')) . '</td>';
|
||||
$NewBadgeRow .= '</tr>';
|
||||
if($Edit) {
|
||||
$this->JsonTarget('#BadgeID_' . $this->Badge->BadgeID, $NewBadgeRow, 'ReplaceWith');
|
||||
$this->InformMessage('Badge updated successfully!');
|
||||
}
|
||||
else {
|
||||
$this->JsonTarget('#Badges tbody', $NewBadgeRow, 'Append');
|
||||
$this->InformMessage('Badge added successfully!');
|
||||
}
|
||||
Redirect('/yaga/badges/settings');
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,16 +132,49 @@ class BadgesController extends DashboardController {
|
||||
|
||||
public function Toggle($BadgeID) {
|
||||
if(!$this->Request->IsPostBack()) {
|
||||
//throw PermissionException('Javascript');
|
||||
throw PermissionException('Javascript');
|
||||
}
|
||||
$this->Permission('Yaga.Reactions.Manage');
|
||||
$this->AddSideMenu('badges/settings');
|
||||
|
||||
|
||||
$Badge = $this->BadgeModel->GetBadge($BadgeID);
|
||||
$Enable = (!$Badge->Enabled) ? TRUE : FALSE;
|
||||
$EnableText = ($Enable) ? 'Yes' : 'No';
|
||||
|
||||
if($Badge->Enabled) {
|
||||
$Enable = FALSE;
|
||||
$ToggleText = T('Disabled');
|
||||
$ActiveClass = 'InActive';
|
||||
}
|
||||
else {
|
||||
$Enable = TRUE;
|
||||
$ToggleText = T('Enabled');
|
||||
$ActiveClass = 'Active';
|
||||
}
|
||||
|
||||
$Slider = Wrap(Wrap(Anchor($ToggleText, 'yaga/badges/toggle/' . $Badge->BadgeID, 'Hijack SmallButton'), 'span', array('class' => "ActivateSlider ActivateSlider-{$ActiveClass}")), 'td');
|
||||
$this->BadgeModel->EnableBadge($BadgeID, $Enable);
|
||||
$this->JsonTarget('#BadgeID_' . $BadgeID . ' td:nth-child(7)', Wrap(Anchor($EnableText, 'yaga/badges/toggle/' . $BadgeID, array('class' => 'Hijack')), 'td'), 'ReplaceWith');
|
||||
$this->JsonTarget('#BadgeID_' . $BadgeID . ' td:nth-child(7)', $Slider, 'ReplaceWith');
|
||||
$this->Render('Blank', 'Utility', 'Dashboard');
|
||||
}
|
||||
|
||||
public function DeletePhoto($BadgeID = FALSE, $TransientKey = '') {
|
||||
// Check permission
|
||||
$this->Permission('Garden.Badges.Manage');
|
||||
|
||||
$RedirectUrl = 'yaga/badges/edit/'.$BadgeID;
|
||||
|
||||
if (Gdn::Session()->ValidateTransientKey($TransientKey)) {
|
||||
// Do removal, set message, redirect
|
||||
$BadgeModel = new BadgeModel();
|
||||
$BadgeModel->SetField($BadgeID, 'Photo', NULL);
|
||||
$this->InformMessage(T('Badge photo has been deleted.'));
|
||||
}
|
||||
if ($this->_DeliveryType == DELIVERY_TYPE_ALL) {
|
||||
Redirect($RedirectUrl);
|
||||
} else {
|
||||
$this->ControllerName = 'Home';
|
||||
$this->View = 'FileNotFound';
|
||||
$this->RedirectUrl = Url($RedirectUrl);
|
||||
$this->Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
design/badges.css
Normal file
5
design/badges.css
Normal file
@ -0,0 +1,5 @@
|
||||
/* Copyright 2013 Zachary Doll */
|
||||
.BadgePhoto {
|
||||
height: 25px;
|
||||
}
|
||||
|
@ -88,5 +88,26 @@ class BadgeModel extends Gdn_Model {
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public function AwardBadge($BadgeID, $UserID) {
|
||||
if($this->BadgeExists($BadgeID)) {
|
||||
if(!$this->UserHasBadge($UserID, $BadgeID)) {
|
||||
$this->SQL->Insert('BadgeAward', array(
|
||||
'BadgeID' => $BadgeID,
|
||||
'UserID' => $UserID,
|
||||
'DateInserted' => date(DATE_ISO8601)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function UserHasBadge($UserID, $BadgeID) {
|
||||
return $this->SQL
|
||||
->Select()
|
||||
->From('BadgeAward')
|
||||
->Where('BadgeID', $ActionID)
|
||||
->Where('UserID', $UserID)
|
||||
->GetCount();
|
||||
}
|
||||
|
||||
}
|
43
rules/class.commentcount.php
Normal file
43
rules/class.commentcount.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php if(!defined('APPLICATION')) exit();
|
||||
include_once 'interface.yagarule.php';
|
||||
/**
|
||||
* This rule awards badges based on a user's join date
|
||||
*
|
||||
* @author Zachary Doll
|
||||
* @since 1.0
|
||||
* @package Yaga
|
||||
*/
|
||||
class CommentCount implements YagaRule{
|
||||
public function AwardCheck($Criteria, $UserID) {
|
||||
$UserModel = new UserModel();
|
||||
$User = $UserModel->GetID($UserID);
|
||||
$InsertDate = strtotime($User->DateInserted);
|
||||
$Days = $Criteria * 24 * 60 * 60;
|
||||
if($InsertDate < time() - $Days) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function CalculationHook() {
|
||||
return 'EntryController_Signin_Handler';
|
||||
}
|
||||
|
||||
public function Description() {
|
||||
$Description = 'This rule checks a users total comment count against the criteria. If the user has more comments than the criteria, this will return true.';
|
||||
return $Description;
|
||||
|
||||
}
|
||||
|
||||
public function AggregationFunction($UserID) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function FriendlyName() {
|
||||
return 'Comment Count Total';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
43
rules/class.discussioncount.php
Normal file
43
rules/class.discussioncount.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php if(!defined('APPLICATION')) exit();
|
||||
include_once 'interface.yagarule.php';
|
||||
/**
|
||||
* This rule awards badges based on a user's join date
|
||||
*
|
||||
* @author Zachary Doll
|
||||
* @since 1.0
|
||||
* @package Yaga
|
||||
*/
|
||||
class DiscussionCount implements YagaRule{
|
||||
public function AwardCheck($Criteria, $UserID) {
|
||||
$UserModel = new UserModel();
|
||||
$User = $UserModel->GetID($UserID);
|
||||
$InsertDate = strtotime($User->DateInserted);
|
||||
$Days = $Criteria * 24 * 60 * 60;
|
||||
if($InsertDate < time() - $Days) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function CalculationHook() {
|
||||
return 'EntryController_Signin_Handler';
|
||||
}
|
||||
|
||||
public function Description() {
|
||||
$Description = 'This rule checks a users discussion count against the criteria. It will return true once the user has as many or more than the given amount.';
|
||||
return $Description;
|
||||
|
||||
}
|
||||
|
||||
public function AggregationFunction($UserID) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function FriendlyName() {
|
||||
return 'Discussion Count Total';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
43
rules/class.joindate.php
Normal file
43
rules/class.joindate.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php if(!defined('APPLICATION')) exit();
|
||||
include_once 'interface.yagarule.php';
|
||||
/**
|
||||
* This rule awards badges based on a user's join date
|
||||
*
|
||||
* @author Zachary Doll
|
||||
* @since 1.0
|
||||
* @package Yaga
|
||||
*/
|
||||
class JoinDate implements YagaRule{
|
||||
public function AwardCheck($Criteria, $UserID) {
|
||||
$UserModel = new UserModel();
|
||||
$User = $UserModel->GetID($UserID);
|
||||
$InsertDate = strtotime($User->DateInserted);
|
||||
$Days = $Criteria * 24 * 60 * 60;
|
||||
if($InsertDate < time() - $Days) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function CalculationHook() {
|
||||
return 'EntryController_Signin_Handler';
|
||||
}
|
||||
|
||||
public function Description() {
|
||||
$Description = 'This rule checks a users join date against the current date. The criteria is the age of the account in days. It will return true if the account is older than this number of days.';
|
||||
return $Description;
|
||||
|
||||
}
|
||||
|
||||
public function AggregationFunction($UserID) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function FriendlyName() {
|
||||
return 'Join Date';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
15
rules/interface.yagarule.php
Normal file
15
rules/interface.yagarule.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php if(!defined('APPLICATION')) exit();
|
||||
/**
|
||||
*
|
||||
* @author Zachary Doll
|
||||
* @since 1.0
|
||||
* @package Yaga
|
||||
*/
|
||||
interface YagaRule {
|
||||
public function AwardCheck($Criteria, $UserID);
|
||||
public function FriendlyName();
|
||||
public function CalculationHook();
|
||||
public function Description();
|
||||
public function AggregationFunction($UserID);
|
||||
}
|
||||
?>
|
@ -1,2 +1,11 @@
|
||||
<?php if (!defined('APPLICATION')) exit();
|
||||
// Application's bootstrap stuff can go here. Define global functions, mess with the Factory, Config modifications.
|
||||
// Load up the rules
|
||||
$Map = Gdn_Autoloader::MAP_LIBRARY;
|
||||
$Context = Gdn_Autoloader::CONTEXT_APPLICATION;
|
||||
$Path = PATH_APPLICATIONS . DS . 'yaga' . DS . 'rules';
|
||||
$Options = array();
|
||||
|
||||
// Set the map options
|
||||
$Options['Extension'] = 'yaga';
|
||||
|
||||
Gdn_Autoloader::RegisterMap($Map, $Context, $Path, $Options);
|
||||
|
@ -43,3 +43,10 @@ $Construct->Table('Badge')
|
||||
->Column('AwardValue', 'int', 0)
|
||||
->Column('Enabled', 'tinyint(1)', '1')
|
||||
->Set($Explicit, $Drop);
|
||||
|
||||
$Construct->Table('BadgeAward')
|
||||
->PrimaryKey('BadgeAwardID')
|
||||
->Column('BadgeID', 'int')
|
||||
->Column('UserID', 'int')
|
||||
->Column('DateInserted', 'datetime')
|
||||
->Set($Explicit, $Drop);
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php if(!defined('APPLICATION')) exit();
|
||||
/* Copyright 2013 Zachary Doll */
|
||||
if(is_object($this->Badge)) {
|
||||
if(property_exists($this, 'Badge')) {
|
||||
echo Wrap(T('Edit Badge'), 'h1');
|
||||
}
|
||||
else {
|
||||
@ -17,9 +17,9 @@ echo $this->Form->Errors();
|
||||
$Photo = $this->Form->GetValue('Photo');
|
||||
if($Photo) {
|
||||
echo Img(Gdn_Upload::Url($Photo));
|
||||
//echo '<br />'.Anchor(T('Delete Photo'),
|
||||
// CombinePaths(array('vanilla/settings/deletecategoryphoto', $this->Category->CategoryID, Gdn::Session()->TransientKey())),
|
||||
//'SmallButton Danger PopConfirm');
|
||||
echo '<br />'.Anchor(T('Delete Photo'),
|
||||
CombinePaths(array('badges/deletephoto', $this->Badge->BadgeID, Gdn::Session()->TransientKey())),
|
||||
'SmallButton Danger PopConfirm');
|
||||
}
|
||||
echo $this->Form->Input('PhotoUpload', 'file');
|
||||
?>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
echo Wrap($this->Title(), 'h1');
|
||||
echo Wrap(Wrap('Add or edit the available badges that can be earned.', 'div'), 'div', array('class' => 'Wrap'));
|
||||
echo Wrap(Anchor('Add Action', 'yaga/badges/add', array('class' => 'Popup SmallButton')), 'div', array('class' => 'Wrap'));
|
||||
echo Wrap(Anchor('Add Action', 'yaga/badges/add', array('class' => 'SmallButton')), 'div', array('class' => 'Wrap'));
|
||||
|
||||
?>
|
||||
<table id="Actions" class="AltRows">
|
||||
@ -21,19 +21,27 @@ echo Wrap(Anchor('Add Action', 'yaga/badges/add', array('class' => 'Popup SmallB
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$Alt = '';
|
||||
$Alt = 'Alt';
|
||||
foreach($this->Data('Badges') as $Badge) {
|
||||
echo '<tr id="BadgeID_' . $Badge->BadgeID . '" data-badgeid="'. $Badge->BadgeID . '"' . ($Alt ? ' class="Alt"' : '') . '>';
|
||||
echo '<td>' . Img($Badge->Photo) . '</td>';
|
||||
echo "<td>$Badge->Name</td>";
|
||||
echo "<td>$Badge->Description</td>";
|
||||
echo "<td>$Badge->RuleClass</td>";
|
||||
echo "<td>$Badge->RuleCriteria</td>";
|
||||
echo "<td>$Badge->AwardValue</td>";
|
||||
$ToggleText = ($Badge->Enabled) ? T('Yes') : T('No');
|
||||
echo '<td>' . Anchor($ToggleText, 'yaga/badges/toggle/' . $Badge->BadgeID, array('class' => 'Hijack')) . '</td>';
|
||||
echo '<td>' . Anchor(T('Edit'), 'yaga/badges/edit/' . $Badge->BadgeID, array('class' => 'Popup SmallButton')) . Anchor(T('Delete'), 'yaga/badges/delete/' . $Badge->BadgeID, array('class' => 'Danger PopConfirm SmallButton')) . '</td>';
|
||||
echo '</tr>';
|
||||
$Alt = $Alt ? '' : 'Alt';
|
||||
$Row = '';
|
||||
// TODO: Show image in pop up rather than linking to it
|
||||
if($Badge->Photo) {
|
||||
$Row .= Wrap(Anchor(Img(Gdn_Upload::Url($Badge->Photo), array('class' => 'BadgePhoto')), Gdn_Upload::Url($Badge->Photo)), 'td');
|
||||
}
|
||||
else {
|
||||
$Row .= Wrap(T('None'), 'td');
|
||||
}
|
||||
$Row .= Wrap($Badge->Name, 'td');
|
||||
$Row .= Wrap($Badge->Description, 'td');
|
||||
$Row .= Wrap($Badge->RuleClass, 'td');
|
||||
$Row .= Wrap($Badge->RuleCriteria, 'td');
|
||||
$Row .= Wrap($Badge->AwardValue, 'td');
|
||||
$ToggleText = ($Badge->Enabled) ? T('Enabled') : T('Disabled');
|
||||
$ActiveClass = ($Badge->Enabled) ? 'Active' : 'InActive';
|
||||
$Row .= Wrap(Wrap(Anchor($ToggleText, 'yaga/badges/toggle/' . $Badge->BadgeID, 'Hijack SmallButton'), 'span', array('class' => "ActivateSlider ActivateSlider-{$ActiveClass}")), 'td');
|
||||
$Row .= Wrap(Anchor(T('Edit'), 'yaga/badges/edit/' . $Badge->BadgeID, array('class' => 'SmallButton')) . Anchor(T('Delete'), 'yaga/badges/delete/' . $Badge->BadgeID, array('class' => 'Danger PopConfirm SmallButton')), 'td');
|
||||
echo Wrap($Row, 'tr', array('id' => 'BadgeID_' . $Badge->BadgeID, 'data-badgeid' => $Badge->BadgeID, 'class' => $Alt));
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
|
Loading…
x
Reference in New Issue
Block a user