Skip to content

Commit

Permalink
Merge pull request #783 from phalcon/3.1.x
Browse files Browse the repository at this point in the history
3.1.2
  • Loading branch information
Jurigag authored May 26, 2017
2 parents 3f39a27 + 0c3324b commit 2feb8b5
Show file tree
Hide file tree
Showing 29 changed files with 863 additions and 224 deletions.
32 changes: 20 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ php:
- 5.5
- 5.6
- 7.0
- 7.1

services:
- memcached
Expand All @@ -35,31 +36,38 @@ cache:
directories:
- vendor
- $HOME/.composer/cache
- $HOME/pear
- $HOME/cphalcon
- $HOME/ext

env:
global:
- ZEND_DONT_UNLOAD_MODULES=1
- CC="ccache gcc"
- PATH="$PATH:~/bin"
- PHALCON_VERSION="v3.1.1"
- PHALCON_VERSION="v3.1.2"

before_install:
- export PHP_MAJOR="$(echo $TRAVIS_PHP_VERSION | cut -d '.' -f 1)"
- export PHP_EXTENSION_DIR=$(php-config --extension-dir)
- phpenv config-rm xdebug.ini || true
- sudo ln -s /home/travis/.phpenv/versions/$(phpenv version-name)/bin/phpize /usr/bin/
- sudo ln -s /home/travis/.phpenv/versions/$(phpenv version-name)/bin/php-config /usr/bin/
- export PHP_MAJOR="$(echo $TRAVIS_PHP_VERSION | cut -d '.' -f 1,2)"
- bash tests/_ci/pear_setup.sh
- bash tests/_ci/install_prereqs_$PHP_MAJOR.sh
- if [[ ! -z "${GH_TOKEN}" ]]; then composer config github-oauth.github.com ${GH_TOKEN}; echo "Configured Github token"; fi;
- travis_retry composer install --prefer-dist --no-interaction --ignore-platform-reqs
- if [ ! -f "$HOME/cphalcon/tests/_ci/phalcon.ini" ]; then git clone -q --depth=1 https://github.com/phalcon/cphalcon.git $HOME/cphalcon >/dev/null 2>&1; fi;

install:
- ( bash tests/_ci/install_prereqs_$PHP_MAJOR.sh )
- travis_retry composer install --prefer-dist --no-interaction --quiet --no-ansi --no-progress --optimize-autoloader --dev --no-suggest --ignore-platform-reqs
# See https://github.com/aerospike/aerospike-client-php/issues/127
- '[[ "${PHP_MAJOR:0:1}" == "7" ]] || bash ${TRAVIS_BUILD_DIR}/tests/_ci/install_aerospike.sh'
- git clone -q --depth=1 https://github.com/phalcon/cphalcon.git -b ${PHALCON_VERSION} >/dev/null 2>&1
- (cd cphalcon/build; bash ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config))
- '[[ "$PHP_MAJOR" == "7" ]] || bash ${TRAVIS_BUILD_DIR}/tests/_ci/install_aerospike.sh'
- if [ ! -f $HOME/ext/$PHP_VERSION/phalcon.so ]; then cd $HOME/cphalcon/build && bash ./install --phpize $(phpenv which phpize) --php-config $(phpenv which php-config) && mkdir -p $HOME/ext/$PHP_VERSION && cp $PHP_EXTENSION_DIR/phalcon.so $HOME/ext/$PHP_VERSION/phalcon.so; fi;
- if [ -f $HOME/ext/$PHP_VERSION/phalcon.so ]; then cp $HOME/ext/$PHP_VERSION/phalcon.so $PHP_EXTENSION_DIR/phalcon.so; fi;
- phpenv config-add $HOME/cphalcon/tests/_ci/phalcon.ini
- phpenv config-add ${TRAVIS_BUILD_DIR}/tests/_ci/redis.ini
- phpenv config-add ${TRAVIS_BUILD_DIR}/tests/_ci/phalcon.ini
# Debug
- php -m
- cd $TRAVIS_BUILD_DIR
- $(phpenv which php) -m
- pecl list
- ipcs -m

before_script:
- stty cols 160
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
New BSD License

Copyright (c) 2011-2016, Phalcon Framework Team
Copyright (c) 2011-2017, Phalcon Framework Team
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
158 changes: 116 additions & 42 deletions Library/Phalcon/Mvc/Model/Behavior/Blameable.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
<?php

namespace Phalcon\Mvc\Model\Behavior;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Behavior;
use Phalcon\Mvc\Model\Behavior\Blameable\Audit;
use Phalcon\Mvc\Model\Behavior\Blameable\AuditDetail;
use Phalcon\Mvc\Model\Behavior\Blameable\AuditDetailInterface;
use Phalcon\Mvc\Model\Behavior\Blameable\AuditInterface;
use Phalcon\Mvc\Model\BehaviorInterface;
use Phalcon\Mvc\ModelInterface;

Expand All @@ -10,56 +16,104 @@
*/
class Blameable extends Behavior implements BehaviorInterface
{
/**
* @var array
*/
protected $snapshot;

/**
* @var array
*/
protected $changedFields;

/**
* @var string
*/
protected $auditClass = Audit::class;

/**
* @var string
*/
protected $auditDetailClass = AuditDetail::class;

/**
* @var callable
*/
protected $userCallback;

/**
* Blameable constructor.
* @param array|null $options
* @throws Exception
*/
public function __construct($options = null)
{
parent::__construct($options);
if (isset($options['auditClass'])) {
if (!in_array(AuditInterface::class, class_implements($options['auditClass']))) {
throw new Exception(
"Your class must implement Phalcon\\Mvc\\Model\\Behavior\\Blameable\\AuditInterface"
);
}
$this->auditClass = $options['auditClass'];
}

if (isset($options['auditDetailClass'])) {
if (!in_array(AuditDetailInterface::class, class_implements($options['auditDetailClass']))) {
throw new Exception(
"Your class must implement Phalcon\\Mvc\\Model\\Behavior\\Blameable\\AuditDetailInterface"
);
}
$this->auditDetailClass = $options['auditDetailClass'];
}

if (isset($options['userCallback'])) {
if (!is_callable($options['userCallback'])) {
throw new Exception("User callback must be callable!");
}
$this->userCallback = $options['userCallback'];
}
}

/**
* {@inheritdoc}
*
* @param string $eventType
* @param string $eventType
* @param \Phalcon\Mvc\ModelInterface $model
*/
public function notify($eventType, ModelInterface $model)
{
//Fires 'logAfterUpdate' if the event is 'afterCreate'
//Fires 'auditAfterCreate' if the event is 'afterCreate'
if ($eventType == 'afterCreate') {
return $this->auditAfterCreate($model);
}

//Fires 'logAfterUpdate' if the event is 'afterUpdate'
//Fires 'auditAfterUpdate' if the event is 'afterUpdate'
if ($eventType == 'afterUpdate') {
return $this->auditAfterUpdate($model);
}

// Fires 'collectData' if the event is 'beforeUpdate'
if ($eventType == 'beforeUpdate') {
return $this->collectData($model);
}
}

/**
* Creates an Audit isntance based on the current enviroment
*
* @param string $type
* @param string $type
* @param \Phalcon\Mvc\ModelInterface $model
* @return Audit
* @return AuditInterface
*/
public function createAudit($type, ModelInterface $model)
{
//Get the session service
$session = $model->getDI()->getSession();

//Get the request service
$request = $model->getDI()->getRequest();

$audit = new Audit();

//Get the username from session
$audit->user_name = $session->get('userName');

//The model who performed the action
$audit->model_name = get_class($model);

//The client IP address
$audit->ipaddress = $request->getClientAddress();

//Action is an update
$audit->type = $type;

//Current time
$audit->created_at = date('Y-m-d H:i:s');
$auditClass = $this->auditClass;
/** @var AuditInterface $audit */
$audit = new $auditClass();
$audit->setUserCallback($this->userCallback);
$audit->setModel($model);
$audit->setType($type);

return $audit;
}
Expand All @@ -72,17 +126,26 @@ public function createAudit($type, ModelInterface $model)
*/
public function auditAfterCreate(ModelInterface $model)
{
//Create a new audit
$audit = $this->createAudit('C', $model);
/** @var AuditInterface|ModelInterface $audit */
$audit = $this->createAudit('C', $model);
/** @var Model\MetaData $metaData */
$metaData = $model->getModelsMetaData();
$fields = $metaData->getAttributes($model);
$details = [];
$fields = $metaData->getAttributes($model);
$columnMap = $metaData->getColumnMap($model);
$details = [];
$auditDetailClass = $this->auditDetailClass;

foreach ($fields as $field) {
$auditDetail = new AuditDetail();
$auditDetail->field_name = $field;
$auditDetail->old_value = null;
$auditDetail->new_value = $model->readAttribute($field);
/** @var AuditDetailInterface $auditDetail */
$auditDetail = new $auditDetailClass();
$auditDetail->setOldValue(null);
if (empty($columnMap)) {
$auditDetail->setFieldName($field);
$auditDetail->setNewValue($model->readAttribute($field));
} else {
$auditDetail->setFieldName($columnMap[$field]);
$auditDetail->setNewValue($model->readAttribute($columnMap[$field]));
}

$details[] = $auditDetail;
}
Expand All @@ -100,24 +163,26 @@ public function auditAfterCreate(ModelInterface $model)
*/
public function auditAfterUpdate(ModelInterface $model)
{
$changedFields = $model->getChangedFields();
$changedFields = $this->changedFields;

if (count($changedFields) == 0) {
return null;
}

//Create a new audit
/** @var AuditInterface|ModelInterface $audit */
$audit = $this->createAudit('U', $model);

//Date the model had before modifications
$originalData = $model->getSnapshotData();
$originalData = $this->snapshot;
$auditDetailClass = $this->auditDetailClass;

$details = [];
foreach ($changedFields as $field) {
$auditDetail = new AuditDetail();
$auditDetail->field_name = $field;
$auditDetail->old_value = $originalData[$field];
$auditDetail->new_value = $model->readAttribute($field);
/** @var AuditDetailInterface $auditDetail */
$auditDetail = new $auditDetailClass();
$auditDetail->setFieldName($field);
$auditDetail->setOldValue($originalData[$field]);
$auditDetail->setNewValue($model->readAttribute($field));

$details[] = $auditDetail;
}
Expand All @@ -126,4 +191,13 @@ public function auditAfterUpdate(ModelInterface $model)

return $audit->save();
}

/**
* @param ModelInterface $model
*/
protected function collectData(ModelInterface $model)
{
$this->snapshot = $model->getSnapshotData();
$this->changedFields = $model->getChangedFields();
}
}
Loading

0 comments on commit 2feb8b5

Please sign in to comment.