Skip to content
This repository has been archived by the owner on Apr 5, 2018. It is now read-only.

Commit

Permalink
Merge branch 'develop' into 'master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Bob Olde Hampsink committed Dec 3, 2014
2 parents ae34e33 + 7603419 commit ce8f191
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 36 deletions.
2 changes: 1 addition & 1 deletion AuditLogPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function getName()

function getVersion()
{
return '0.2.8';
return '0.3.0';
}

function getDeveloper()
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ The plugin's folder should be named "auditlog"

Changelog
=================
###0.3.0###
- Removed ability to clear log - you can uninstall the plugin to do this
- Added a date range selector
- Made sorting work
- Added ModifyAuditLogTableAttributes and getAuditLogTableAttributeHtml hooks

Warning! This version is updated for Craft 2.3 and does NOT work on Craft 2.2

###0.2.8###
- Fixed a bug where the user couldn't be shown in some cases

Expand Down
18 changes: 0 additions & 18 deletions controllers/AuditLogController.php

This file was deleted.

115 changes: 106 additions & 9 deletions elementtypes/AuditLogElementType.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,42 +28,78 @@ public function getStatuses()
// Define table column names
public function defineTableAttributes($source = null)
{
return array(

// Define default attributes
$attributes = array(
'type' => Craft::t('Type'),
'user' => Craft::t('User'),
'origin' => Craft::t('Origin'),
'dateUpdated' => Craft::t('Modified'),
'changes' => Craft::t('Changes')
'dateUpdated' => Craft::t('Modified')
);

// Allow plugins to modify the attributes
craft()->plugins->call('modifyAuditLogTableAttributes', array(&$attributes, $source));

// Set changes at last
$attributes['changes'] = Craft::t('Changes');

// Return the attributes
return $attributes;

}

public function getTableAttributeHtml(BaseElementModel $element, $attribute)
{

// First give plugins a chance to set this
$pluginAttributeHtml = craft()->plugins->callFirst('getAuditLogTableAttributeHtml', array($element, $attribute), true);

// Check if that had a valid result
if($pluginAttributeHtml) {

// Return it
return $pluginAttributeHtml;

}

// Modify custom attributes
switch ($attribute)
{

// Format dates
case 'dateCreated':
case 'dateUpdated':
{
return craft()->dateFormatter->formatDateTime($element->$attribute);
}

// Return clickable user link
case 'user':
{
$user = $element->getUser();
return $user ? '<a href="' . $user->getCpEditUrl() . '">' . $user . '</a>' : Craft::t('Guest');
}

// Return clickable event origin
case 'origin':
{
return '<a href="' . preg_replace('/' . craft()->config->get('cpTrigger') . '\//', '', UrlHelper::getUrl($element->origin), 1) . '">' . $element->origin . '</a>';
}

// Return view changes button
case 'changes':
{
return '<a class="btn" href="' . UrlHelper::getCpUrl('auditlog/' . $element->id) . '">' . Craft::t('View') . '</a>';
}

// Default behavior
default:
{
return $element->$attribute;
}

}

}

// Define criteria
Expand All @@ -74,7 +110,9 @@ public function defineCriteriaAttributes()
'userId' => AttributeType::Number,
'origin' => AttributeType::String,
'modified' => AttributeType::DateTime,
'status' => AttributeType::String
'status' => AttributeType::String,
'before' => AttributeType::DateTime,
'after' => AttributeType::DateTime
);
}

Expand Down Expand Up @@ -120,19 +158,78 @@ public function getSources($context = null)
}

// Return the html
public function getIndexHtml($criteria, $disabledElementIds, $viewState, $sourceKey, $context)
public function getIndexHtml($criteria, $disabledElementIds, $viewState, $sourceKey, $context, $includeContainer, $showCheckboxes)
{
$variables = array(
'viewMode' => $viewState['mode'],
'context' => $context,
'elementType' => new ElementTypeVariable($this),
'disabledElementIds' => $disabledElementIds,
'attributes' => $this->defineTableAttributes($sourceKey),
'elements' => craft()->auditLog->log($criteria)
'showCheckboxes' => $showCheckboxes,
);

$template = '_elements/'.$viewState['mode'].'view/'.(!$criteria->offset ? 'container' : 'elements');

// In case of "score" (searching)
if(!empty($viewState['order']) && $viewState['order'] == 'score') {

// Order by id
$criteria->order = 'id';

} else {

// Get sortable attribuets
$sortableAttributes = $this->defineSortableAttributes();

if($sortableAttributes) {

// Get order and sort
$order = (!empty($viewState['order']) && isset($sortableAttributes[$viewState['order']])) ? $viewState['order'] : array_shift(array_keys($sortableAttributes));
$sort = (!empty($viewState['sort']) && in_array($viewState['sort'], array('asc', 'desc'))) ? $viewState['sort'] : 'asc';

// Set sort on criteria
$criteria->order = $order.' '.$sort;

}

}

switch($viewState['mode']) {

case 'table':

// Get the table columns
$variables['attributes'] = $this->defineTableAttributes($sourceKey);

break;

}

// Get elements
$variables['elements'] = craft()->auditLog->log($criteria);

// Get template
$template = '_elements/'.$viewState['mode'].'view/'.($includeContainer ? 'container' : 'elements');

// Return template
return craft()->templates->render($template, $variables);

}

// Set sortable attributes
public function defineSortableAttributes()
{

// Set modified first
$attributes['dateUpdated'] = Craft::t('Modified');

// Get table attributes
$attributes = array_merge($attributes, $this->defineTableAttributes());

// Unset unsortable attributes
unset($attributes['user'], $attributes['changes']);

// Return attributes
return $attributes;

}

}
28 changes: 21 additions & 7 deletions services/AuditLogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,44 @@ class AuditLogService extends BaseApplicationComponent

public function log($criteria)
{

// Build specific criteria
$condition = '';
$params = array();

// Check for date after
if(!empty($criteria->after)) {
$condition .= 'dateUpdated > :after and ';
$params[':after'] = DateTimeHelper::formatTimeForDb($criteria->after);
}

// Check for date before
if(!empty($criteria->before)) {
$condition .= 'dateUpdated < :before and ';
$params[':before'] = DateTimeHelper::formatTimeForDb($criteria->before);
}

// Check for type
if(!empty($criteria->type)) {
$condition .= 'type = :type and ';
$params[':type'] = $criteria->type;
}

// Check for status
if(!empty($criteria->status)) {
$condition .= 'status = :status and ';
$params[':status'] = $criteria->status;
}

// Search
if(!empty($criteria->search)) {
$condition .= 'origin like :search and ';
$params[':search'] = '%' . addcslashes($criteria->search, '%_') . '%';
}
$condition = substr($condition, 0, -5);


// Get logs from record
return AuditLogModel::populateModels(AuditLogRecord::model()->findAll(array(
'order' => 'id desc',
'limit' => $criteria->limit,
'offset' => $criteria->offset,
'condition' => $condition,
'order' => $criteria->order,
'condition' => substr($condition, 0, -5),
'params' => $params
)));

Expand Down
83 changes: 82 additions & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,93 @@
{% set title = "Audit Log"|t %}
{% set elementType = 'AuditLog' %}

{% block initCss %}
.buttons {
margin: 10px 0px;
}
.buttons th, .buttons td {
padding: 0px 0px 5px 0px;
}
{% endblock %}
{% includeCss block('initCss') %}

{% block sidebar %}
{% if currentUser.admin %}
<nav>
<ul>
<li class="heading"><span>{{ "Date range"|t }}</span></li>
</ul>
</nav>
<div class="buttons">
<a class="btn submit" data-icon="refresh" href="{{ actionUrl('auditLog/clear') }}" onclick="return confirm('{{ "Are you sure you want to clear all logs?"|t }}')">{{ "Clear"|t }}</a>
<form method="post" accept-charset="utf-8">
<input type="hidden" name="elementType" value="AuditLog">
<table>
<tr>
<th style="width: 40%;">{{ "From"|t }}</th>
<td>
{% include '_includes/forms/date' with {
'id': 'auditlog-modified-from',
'value': now|date_modify('-7 days')
} %}
</td>
</tr>
<tr>
<th style="width: 40%;">{{ "To"|t }}</th>
<td>
{% include '_includes/forms/date' with {
'id': 'auditlog-modified-to',
'value': now
} %}
</td>
</tr>
</table>
</form>
</div>
<nav>
<ul>
<li class="heading"><span>{{ "Log"|t }}</span></li>
</ul>
</nav>
{% endif %}

{{ parent() }}
{% endblock %}

{% block initJs %}
// Init with datepicker values
Craft.elementIndex = Craft.createElementIndex('AuditLog', $('#main'), {
context: 'index',
showStatusMenu: 'auto',
showLocaleMenu: 'auto',
storageKey: 'elementindex.AuditLog',
criteria: {
after: {
date: $('#auditlog-modified-from-date').val()
},
before: {
date: $('#auditlog-modified-to-date').val()
}
}
})

// Sort descending
Craft.elementIndex.setSelecetedSourceState('sort', 'desc');

// When a datepicker changes
$(document).on('change', 'input.hasDatepicker', function() {

// Get new criteria values
Craft.elementIndex.settings.criteria = {
after: {
date: $('#auditlog-modified-from-date').val()
},
before: {
date: $('#auditlog-modified-to-date').val()
}
};

// Update elements
Craft.elementIndex.updateElements();

});
{% endblock %}
Loading

0 comments on commit ce8f191

Please sign in to comment.