- Fix: Source serialization of Notification ActiveJob

- Enh: Added 'requireSource' & 'requireOriginator' flags in SocialActivities
This commit is contained in:
Lucas Bartholemy 2018-07-30 13:08:03 +02:00
parent 7b981d6caa
commit 73f04d0e24
8 changed files with 140 additions and 36 deletions

View File

@ -8,6 +8,7 @@
namespace humhub\components;
use humhub\components\behaviors\PolymorphicRelation;
use humhub\libs\Helpers;
use humhub\modules\content\models\Content;
use Yii;
@ -43,6 +44,12 @@ abstract class SocialActivity extends \yii\base\BaseObject implements rendering\
*/
public $originator;
/**
* @var bool ensure originator existence
* @since 1.3
*/
public $requireOriginator = true;
/**
* The source instance which created this activity
*
@ -50,6 +57,12 @@ abstract class SocialActivity extends \yii\base\BaseObject implements rendering\
*/
public $source;
/**
* @var bool ensure source existence
* @since 1.3
*/
public $requireSource = true;
/**
* @var string the module id which this activity belongs to (required)
*/
@ -362,6 +375,23 @@ abstract class SocialActivity extends \yii\base\BaseObject implements rendering\
return RichText::preview($content->getContentDescription(), $maxLength);
}
/**
* Validates the existence of required attributes
*
* @return bool
*/
public function validate() {
if (empty($this->source) && $this->requireSource) {
return false;
}
if (empty($this->originator) && $this->requireOriginator) {
return false;
}
return true;
}
/**
* Serializes the $source and $originator fields.
*
@ -372,8 +402,17 @@ abstract class SocialActivity extends \yii\base\BaseObject implements rendering\
*/
public function serialize()
{
$sourceClass = null;
$sourcePk = null;
if ($this->source) {
$sourceClass = get_class($this->source);
$sourcePk = $this->source->getPrimaryKey();
}
return serialize([
'source' => $this->source,
'sourceClass' => $sourceClass,
'sourcePk' => $sourcePk,
'originator_id' => $this->originator->id
]);
}
@ -389,9 +428,25 @@ abstract class SocialActivity extends \yii\base\BaseObject implements rendering\
{
$this->init();
$unserializedArr = unserialize($serialized);
if(isset($unserializedArr['originator_id'])) {
$this->from(User::findOne(['id' => $unserializedArr['originator_id']]));
$user = User::findOne(['id' => $unserializedArr['originator_id']]);
if ($user !== null) {
$this->from($user);
}
}
$this->about($unserializedArr['source']);
// Temporary for 1.3.0-beta.2 to 1.3.0-beta.3 updates with existing queue record
if (isset($unserializedArr['source'])) {
$this->about($unserializedArr['source']);
}
if (!empty($unserializedArr['sourceClass']) && !empty($unserializedArr['sourcePk'])) {
$source = PolymorphicRelation::loadActiveRecord($unserializedArr['sourceClass'], $unserializedArr['sourcePk']);
if ($source !== null) {
$this->about($source);
}
}
}
}

View File

@ -8,9 +8,13 @@
namespace humhub\components\behaviors;
use Exception;
use ReflectionClass;
use ReflectionException;
use Yii;
use yii\base\Behavior;
use yii\db\Exception;
use yii\db\ActiveRecord;
use yii\db\BaseActiveRecord;
/**
* PolymorphicRelations behavior provides simple support for polymorphic relations in ActiveRecords.
@ -51,34 +55,14 @@ class PolymorphicRelation extends Behavior
return $this->_cached;
}
$object = static::loadActiveRecord(
$this->owner->getAttribute($this->classAttribute),
$this->owner->getAttribute($this->pkAttribute)
);
$className = $this->owner->getAttribute($this->classAttribute);
if ($className == "") {
return null;
}
if (!class_exists($className)) {
Yii::error("Underlying object class " . $className . " not found!");
return null;
}
if (!method_exists($className, 'tableName')) {
// Avoids failures when running integrity checks etc.
return null;
}
try {
$tableName = $className::tableName();
$object = $className::find()->where([$tableName . '.id' => $this->owner->getAttribute($this->pkAttribute)])->one();
if ($object !== null && $this->validateUnderlyingObjectType($object)) {
$this->_cached = $object;
return $object;
}
} catch (\Exception $e) {
// Avoid failures when running integrity checks etc.
Yii::error($e);
if ($object !== null && $this->validateUnderlyingObjectType($object)) {
$this->_cached = $object;
return $object;
}
return null;
@ -127,7 +111,44 @@ class PolymorphicRelation extends Behavior
}
Yii::error('Got invalid underlying object type! (' . $object->className() . ')');
return false;
}
/**
* Loads an active record based on classname and primary key.
*
* @param $className
* @param $primaryKey
* @return null|ActiveRecord
*/
public static function loadActiveRecord($className, $primaryKey)
{
try {
$class = new ReflectionClass($className);
} catch (ReflectionException $e) {
Yii::error('Could not load polymorphic relation! Class (' . $e->getMessage() . ')');
return null;
}
if (!$class->isSubclassOf(BaseActiveRecord::class)) {
Yii::error('Could not load polymorphic relation! Class (Class is no ActiveRecord: ' . $className . ')');
return null;
}
try {
$primaryKeyNames = $className::primaryKey();
if (count($primaryKey) !== 1) {
Yii::error('Could not load polymorphic relation! Only one primary key is supported!');
return null;
}
return $className::findOne([$primaryKeyNames[0] => $primaryKey]);
} catch (Exception $ex) {
Yii::error('Could not load polymorphic relation! Error: "' . $ex->getMessage());
}
return null;
}
}

View File

@ -21,6 +21,9 @@ HumHub Change Log
- Fix #2700: Prevent GroupManager access to system admin group management
- Enh: Styled user deletion view
- Fixed: Space and User Admin Filterbar padding
- Fix: Source serialization of Notification ActiveJob
- Enh: Added 'requireSource' & 'requireOriginator' flags in SocialActivities
1.3.0-beta.2 (July 18, 2018)
-----------------------------

View File

@ -33,6 +33,11 @@ Added new user status (User::SOFT_DELETED). You can find more information here:
Moved all form and field related widgets from `humhub\widgets` to `humhub\modules\ui\form\widgets` namespace.
There is a compatibility layer for the 1.3 release.
### Social Activities (Notification & Activities)
- Added new 'requireOriginator' flag with default to true
- Added new 'requireSoruce' flag with default to true
### Deprecations
- `humhub\components\Theme.php` -> `humhub\modules\ui\view\components\Theme`

View File

@ -29,6 +29,16 @@ class NewVersionAvailable extends BaseNotification
*/
public $moduleId = 'admin';
/**
* @inheritdoc
*/
public $requireOriginator = false;
/**
* @inheritdoc
*/
public $requireSource = false;
/**
* @inheritdoc
*/

View File

@ -117,7 +117,7 @@ class NewComment extends \humhub\modules\notification\components\BaseNotificatio
private function getGroupTitle()
{
$user = $this->record->user;
$contentRecord = $this->getCommentedRecord();
$contentInfo = $this->getContentInfo($this->getCommentedRecord());

View File

@ -218,6 +218,10 @@ abstract class BaseNotification extends SocialActivity
*/
public function saveRecord(User $user)
{
if (!$this->validate()) {
return false;
}
$notification = new Notification([
'user_id' => $user->id,
'class' => static::class,
@ -240,9 +244,12 @@ abstract class BaseNotification extends SocialActivity
static::class . ' ' .
print_r($notification->getErrors(), true)
);
return false;
}
$this->record = $notification;
return true;
}
/**

View File

@ -73,9 +73,12 @@ class NotificationManager
continue;
}
$notification->saveRecord($user);
foreach ($this->getTargets($user) as $target) {
$target->send($notification, $user);
if ($notification->saveRecord($user)) {
foreach ($this->getTargets($user) as $target) {
$target->send($notification, $user);
}
} else {
Yii::debug('Could not store notification '.get_class($notification). ' for user '. $user->id);
}
$processed[] = $user->id;