-
-
-
-
-= Form::close() ?>
diff --git a/plugins/rainlab/notify/interfaces/Action.php b/plugins/rainlab/notify/interfaces/Action.php
deleted file mode 100644
index 011cc13..0000000
--- a/plugins/rainlab/notify/interfaces/Action.php
+++ /dev/null
@@ -1,31 +0,0 @@
- [
- 'name' => 'Notify',
- 'description' => 'Notification services',
- ],
- 'notifications' => [
- 'menu_label' => 'Notification rules',
- 'menu_description' => 'Manage the events and actions that trigger notifications.',
- 'name' => 'Name',
- 'code' => 'Code',
- 'notification_rule' => 'Notification rule',
- 'add_notification_rule' => 'Add notification rule',
- ],
- 'action' => [
- 'add_notification_action' => 'Add notification action',
- ],
- 'permissions' => [
- 'manage_notifications' => 'Notifications management',
- ],
-];
diff --git a/plugins/rainlab/notify/lang/ro/lang.php b/plugins/rainlab/notify/lang/ro/lang.php
deleted file mode 100644
index cfe1153..0000000
--- a/plugins/rainlab/notify/lang/ro/lang.php
+++ /dev/null
@@ -1,22 +0,0 @@
- [
- 'name' => 'Notificari',
- 'description' => 'Servicii notificari',
- ],
- 'notifications' => [
- 'menu_label' => 'Reguli notificari',
- 'menu_description' => 'Gestionati evenimentele si actiunile care declanșează notificari',
- 'name' => 'Nume',
- 'code' => 'Cod',
- 'notification_rule' => 'Regula notificare',
- 'add_notification_rule' => 'Adauga o regula pentru notificare',
- ],
- 'action' => [
- 'add_notification_action' => 'Adauga o actiune pentru notificare',
- ],
- 'permissions' => [
- 'manage_notifications' => 'Managementul notificarilor',
- ],
-];
diff --git a/plugins/rainlab/notify/lang/ru/lang.php b/plugins/rainlab/notify/lang/ru/lang.php
deleted file mode 100644
index 1ce8b27..0000000
--- a/plugins/rainlab/notify/lang/ru/lang.php
+++ /dev/null
@@ -1,22 +0,0 @@
- [
- 'name' => 'Уведомления',
- 'description' => 'Службы уведомлений',
- ],
- 'notifications' => [
- 'menu_label' => 'Правила уведомлений',
- 'menu_description' => 'Управление событиями и действиями, которые вызывают уведомления.',
- 'name' => 'Название',
- 'code' => 'Код',
- 'notification_rule' => 'Правило уведомления',
- 'add_notification_rule' => 'Добавить правило',
- ],
- 'action' => [
- 'add_notification_action' => 'Добавить действие',
- ],
- 'permissions' => [
- 'manage_notifications' => 'Управление уведомлениями',
- ],
-];
diff --git a/plugins/rainlab/notify/lang/sl/lang.php b/plugins/rainlab/notify/lang/sl/lang.php
deleted file mode 100644
index addc3ea..0000000
--- a/plugins/rainlab/notify/lang/sl/lang.php
+++ /dev/null
@@ -1,22 +0,0 @@
- [
- 'name' => 'Obvestila',
- 'description' => 'Storitve obveščanja',
- ],
- 'notifications' => [
- 'menu_label' => 'Nastavitve obveščanja',
- 'menu_description' => 'Upravljanje dogodkov in dejanj, ki prožijo obvestila.',
- 'name' => 'Ime',
- 'code' => 'Koda',
- 'notification_rule' => 'Pravilo obveščanja',
- 'add_notification_rule' => 'Dodaj pravilo obveščanja',
- ],
- 'action' => [
- 'add_notification_action' => 'Dodaj dejanje obveščanja',
- ],
- 'permissions' => [
- 'manage_notifications' => 'Upravljanje z nastavitvami obveščanja',
- ],
-];
diff --git a/plugins/rainlab/notify/lang/tr/lang.php b/plugins/rainlab/notify/lang/tr/lang.php
deleted file mode 100644
index b64f80b..0000000
--- a/plugins/rainlab/notify/lang/tr/lang.php
+++ /dev/null
@@ -1,22 +0,0 @@
- [
- 'name' => 'Bildirim',
- 'description' => 'Bildirim Servisi',
- ],
- 'notifications' => [
- 'menu_label' => 'Bildirim kuralları',
- 'menu_description' => 'Bildirimleri tetikleyen olayları ve eylemleri yönetin.',
- 'name' => 'İsim',
- 'code' => 'Kod',
- 'notification_rule' => 'Bildirim kuralı',
- 'add_notification_rule' => 'Bildirim kuralı ekle',
- ],
- 'action' => [
- 'add_notification_action' => 'Bildirim eylemi ekle',
- ],
- 'permissions' => [
- 'manage_notifications' => 'Bildirim yönetimi',
- ],
-];
diff --git a/plugins/rainlab/notify/lang/zh-tw/lang.php b/plugins/rainlab/notify/lang/zh-tw/lang.php
deleted file mode 100644
index bd5e943..0000000
--- a/plugins/rainlab/notify/lang/zh-tw/lang.php
+++ /dev/null
@@ -1,22 +0,0 @@
- [
- 'name' => '通知',
- 'description' => '通知系統',
- ],
- 'notifications' => [
- 'menu_label' => '通知規則',
- 'menu_description' => '管理觸發通知的事件及動作。',
- 'name' => '名稱',
- 'code' => '代碼',
- 'notification_rule' => '通知規則',
- 'add_notification_rule' => '新增通知規則',
- ],
- 'action' => [
- 'add_notification_action' => '新增通知動作',
- ],
- 'permissions' => [
- 'manage_notifications' => '管理通知功能',
- ],
-];
diff --git a/plugins/rainlab/notify/models/Notification.php b/plugins/rainlab/notify/models/Notification.php
deleted file mode 100644
index 57aa20c..0000000
--- a/plugins/rainlab/notify/models/Notification.php
+++ /dev/null
@@ -1,249 +0,0 @@
- [],
- ];
-
- /**
- * Mark the notification as read.
- *
- * @return void
- */
- public function markAsRead()
- {
- if (is_null($this->read_at)) {
- $this->forceFill(['read_at' => $this->freshTimestamp()])->save();
- }
- }
-
- /**
- * Determine if a notification has been read.
- *
- * @return bool
- */
- public function read()
- {
- return $this->read_at !== null;
- }
-
- /**
- * Determine if a notification has not been read.
- *
- * @return bool
- */
- public function unread()
- {
- return $this->read_at === null;
- }
-
- /**
- * Get the entity's unread notifications.
- */
- public function scopeApplyUnread($query)
- {
- return $query->whereNull('read_at');
- }
-
- /**
- * Get the entity's read notifications.
- */
- public function scopeApplyRead($query)
- {
- return $query->whereNotNull('read_at');
- }
-
- /**
- * Get the parsed body of the announcement.
- *
- * @return string
- */
- public function getParsedBodyAttribute()
- {
- return Markdown::parse($this->body);
- }
-
- /**
- * Get the description of the notification
- *
- * @return string
- */
- public function getDescriptionAttribute()
- {
- $e = new $this->event_type;
-
- if($e instanceof MessageReceivedEvent) {
-
- return trans('validation.new_message');
-
- } elseif($e instanceof ProductReviewedEvent) {
-
- return trans('validation.product_reviewed');
-
- } elseif($e instanceof PaymentReviewedEvent) {
-
- return trans('validation.payment_reviewed');
- } elseif($e instanceof PaymentGiftedEvent) {
-
- return trans('validation.payment_gifted');
- }
-
- return 'Unknown type notification';
- }
-
- /**
- * Get the localized description of the notification for api
- *
- * @return string
- */
- public function getDescriptionForApiAttribute()
- {
- $e = new $this->event_type;
-
- if($e instanceof MessageReceivedEvent) {
-
- return [
- 'ru' => trans('validation.new_message', [], 'ru'),
- 'en' => trans('validation.new_message', [], 'en'),
- 'tm' => trans('validation.new_message', [], 'tm'),
- ];
-
- } elseif($e instanceof ProductReviewedEvent) {
-
- return [
- 'ru' => trans('validation.product_reviewed', [], 'ru'),
- 'en' => trans('validation.product_reviewed', [], 'en'),
- 'tm' => trans('validation.product_reviewed', [], 'tm'),
- ];
-
- } elseif($e instanceof PaymentReviewedEvent) {
-
- return [
- 'ru' => trans('validation.payment_reviewed', [], 'ru'),
- 'en' => trans('validation.payment_reviewed', [], 'en'),
- 'tm' => trans('validation.payment_reviewed', [], 'tm'),
- ];
- } elseif($e instanceof PaymentGiftedEvent) {
-
- return [
- 'ru' => trans('validation.payment_gifted', [], 'ru'),
- 'en' => trans('validation.payment_gifted', [], 'en'),
- 'tm' => trans('validation.payment_gifted', [], 'tm'),
- ];
- }
-
- return 'Unknown type notification';
- }
-
- /**
- * Get the screen where to redirect when clicking on the notification
- *
- * @return string
- */
- public function getRedirectToScreenForApiAttribute()
- {
- $e = new $this->event_type;
-
- if($e instanceof MessageReceivedEvent) {
-
- return 'messages_screen';
-
- } elseif($e instanceof ProductReviewedEvent) {
-
- return 'my_posts_screen';
-
- } elseif($e instanceof PaymentReviewedEvent) {
-
- return 'balance_history_screen';
-
- } elseif($e instanceof PaymentGiftedEvent) {
-
- return 'balance_history_screen';
-
- }
-
- return 'main_screen';
- }
-
- /**
- * Get the link where to redirect when the notification is clicked
- *
- * @return string
- */
- public function getLinkAttribute()
- {
- $e = new $this->event_type;
-
- if($e instanceof MessageReceivedEvent) {
-
- return \Url::to('/messages');
-
- } elseif($e instanceof ProductReviewedEvent) {
-
- return \Url::to('/my-posts');
-
- } elseif($e instanceof PaymentReviewedEvent) {
-
- return \Url::to('/balans-taryhy');
- } elseif($e instanceof PaymentGiftedEvent) {
-
- return \Url::to('/balans-taryhy');
- }
-
- return \Url::to('/');
- }
-}
diff --git a/plugins/rainlab/notify/models/NotificationRule.php b/plugins/rainlab/notify/models/NotificationRule.php
deleted file mode 100644
index 8db57a4..0000000
--- a/plugins/rainlab/notify/models/NotificationRule.php
+++ /dev/null
@@ -1,289 +0,0 @@
- 'required'
- ];
-
- /**
- * @var array Relations
- */
- public $hasMany = [
- 'rule_conditions' => [
- RuleCondition::class,
- 'key' => 'rule_host_id',
- 'conditions' => 'rule_parent_id is null',
- 'delete' => true
- ],
- 'rule_actions' => [
- RuleAction::class,
- 'key' => 'rule_host_id',
- 'delete' => true
- ],
- ];
-
- /**
- * Kicks off this notification rule, fires the event to obtain its parameters,
- * checks the rule conditions evaluate as true, then spins over each action.
- */
- public function triggerRule()
- {
- $params = $this->getEventObject()->getParams();
- $rootCondition = $this->rule_conditions->first();
-
- if ($rootCondition && !$rootCondition->getConditionObject()->isTrue($params)) {
- return false;
- }
-
- foreach ($this->rule_actions as $action) {
- $action->setRelation('notification_rule', $this);
- $action->triggerAction($params);
- }
- }
-
- /**
- * Returns extra conditions provided by the event.
- * @return array
- */
- public function getExtraConditionRules()
- {
- $rules = [];
-
- $classes = $this->getEventObject()->defineConditions();
-
- foreach ($classes as $class) {
- $rules[$class] = new $class;
- }
-
- return $rules;
- }
-
- /**
- * Extends this class with the event class
- * @param string $class Class name
- * @return boolean
- */
- public function applyEventClass($class = null)
- {
- if (!$class) {
- $class = $this->class_name;
- }
-
- if (!$class) {
- return false;
- }
-
- if (!$this->isClassExtendedWith($class)) {
- $this->extendClassWith($class);
- }
-
- $this->class_name = $class;
- $this->event_name = Lang::get(array_get($this->eventDetails(), 'name', 'Unknown'));
- return true;
- }
-
- /**
- * Returns the event class extension object.
- * @return \RainLab\Notify\Classes\NotificationEvent
- */
- public function getEventObject()
- {
- $this->applyEventClass();
-
- return $this->asExtension($this->getEventClass());
- }
-
- public function getEventClass()
- {
- return $this->class_name;
- }
-
- //
- // Events
- //
-
- public function afterFetch()
- {
- $this->applyEventClass();
- }
-
- public function beforeValidate()
- {
- if (!$this->applyEventClass()) {
- return;
- }
- }
-
- //
- // Scopes
- //
-
- public function scopeApplyEnabled($query)
- {
- return $query->where('is_enabled', true);
- }
-
- public function scopeApplyClass($query, $class)
- {
- if (!is_string($class)) {
- $class = get_class($class);
- }
-
- return $query->where('class_name', $class);
- }
-
- //
- // Presets
- //
-
- /**
- * Returns an array of rule codes and descriptions.
- * @return array
- */
- public static function listRulesForEvent($eventClass)
- {
- $results = [];
-
- $dbRules = self::applyClass($eventClass)->get();
- $presets = (array) EventBase::findEventPresetsByClass($eventClass);
-
- foreach ($dbRules as $dbRule) {
- if ($dbRule->code) {
- unset($presets[$dbRule->code]);
- }
-
- if ($dbRule->is_enabled) {
- $results[] = $dbRule;
- }
- }
-
- foreach ($presets as $code => $preset) {
- if ($newPreset = self::createFromPreset($code, $preset)) {
- $results[] = $newPreset;
- }
- }
-
- return $results;
- }
-
- /**
- * Syncronise all file-based presets to the database.
- * @return void
- */
- public static function syncAll()
- {
- $presets = (array) EventBase::findEventPresets();
- $dbRules = self::where('code', '!=', '')->whereNotNull('code')->lists('is_custom', 'code');
- $newRules = array_diff_key($presets, $dbRules);
-
- /*
- * Clean up non-customized templates
- */
- foreach ($dbRules as $code => $isCustom) {
- if ($isCustom) {
- continue;
- }
-
- if (!array_key_exists($code, $presets) && ($record = self::whereCode($code)->first())) {
- $record->delete();
- }
- }
-
- /*
- * Create new rules
- */
- foreach ($newRules as $code => $preset) {
- self::createFromPreset($code, $preset);
- }
- }
-
- public static function createFromPreset($code, $preset)
- {
- $actions = array_get($preset, 'items');
- if (!$actions || !is_array($actions)) {
- return;
- }
-
- $newRule = new self;
- $newRule->code = $code;
- $newRule->is_enabled = 1;
- $newRule->is_custom = 0;
- $newRule->name = array_get($preset, 'name');
- $newRule->class_name = array_get($preset, 'event');
- $newRule->forceSave();
-
- // Add the actions
- foreach ($actions as $action) {
- $params = array_except($action, 'action');
-
- $newAction = new RuleAction;
- $newAction->class_name = array_get($action, 'action');
- $newAction->notification_rule = $newRule;
- $newAction->fill($params);
- $newAction->forceSave();
- }
-
- // Add the conditions
- $conditions = array_get($preset, 'conditions');
- if (!$conditions || !is_array($conditions)) {
- return $newRule;
- }
-
- // Create the root condition
- $rootCondition = new RuleCondition();
- $rootCondition->rule_host_type = ConditionBase::TYPE_ANY;
- $rootCondition->class_name = $rootCondition->getRootConditionClass();
- $rootCondition->notification_rule = $newRule;
- $rootCondition->save();
-
- // Add the sub conditions
- foreach ($conditions as $condition) {
- $params = array_except($condition, 'condition');
- $newCondition = new RuleCondition();
- $newCondition->class_name = array_get($condition, 'condition');
- $newCondition->parent = $rootCondition;
- $newCondition->fill($params);
- $newCondition->forceSave();
- }
-
- return $newRule;
- }
-}
diff --git a/plugins/rainlab/notify/models/RuleAction.php b/plugins/rainlab/notify/models/RuleAction.php
deleted file mode 100644
index 21a621f..0000000
--- a/plugins/rainlab/notify/models/RuleAction.php
+++ /dev/null
@@ -1,164 +0,0 @@
- [NotificationRule::class, 'key' => 'rule_host_id'],
- ];
-
- public function triggerAction($params)
- {
- try {
- $this->getActionObject()->triggerAction($params);
- }
- catch (Exception $ex) {
- // We could log the error here, for now we should suppress
- // any exceptions to let other actions proceed as normal
- traceLog('Error with ' . $this->getActionClass());
- traceLog($ex);
- }
- }
-
- /**
- * Extends this model with the action class
- * @param string $class Class name
- * @return boolean
- */
- public function applyActionClass($class = null)
- {
- if (!$class) {
- $class = $this->class_name;
- }
-
- if (!$class) {
- return false;
- }
-
- if (!$this->isClassExtendedWith($class)) {
- $this->extendClassWith($class);
- }
-
- $this->class_name = $class;
- return true;
- }
-
- public function beforeSave()
- {
- $this->setCustomData();
- }
-
- public function afterSave()
- {
- // Make sure that this record is removed from the DB after being removed from a rule
- $removedFromRule = $this->rule_host_id === null && $this->getOriginal('rule_host_id');
- if ($removedFromRule && !$this->notification_rule()->withDeferred(post('_session_key'))->exists()) {
- $this->delete();
- }
- }
-
- public function applyCustomData()
- {
- $this->setCustomData();
- $this->loadCustomData();
- }
-
- protected function loadCustomData()
- {
- $this->setRawAttributes((array) $this->getAttributes() + (array) $this->config_data, true);
- }
-
- protected function setCustomData()
- {
- if (!$actionObj = $this->getActionObject()) {
- throw new SystemException(sprintf('Unable to find action object [%s]', $this->getActionClass()));
- }
-
- /*
- * Spin over each field and add it to config_data
- */
- $config = $actionObj->getFieldConfig();
-
- /*
- * Action class has no fields
- */
- if (!isset($config->fields)) {
- return;
- }
-
- $staticAttributes = ['action_text'];
-
- $fieldAttributes = array_merge($staticAttributes, array_keys($config->fields));
-
- $dynamicAttributes = array_only($this->getAttributes(), $fieldAttributes);
-
- $this->config_data = $dynamicAttributes;
-
- $this->setRawAttributes(array_except($this->getAttributes(), $fieldAttributes));
- }
-
- public function afterFetch()
- {
- $this->applyActionClass();
- $this->loadCustomData();
- }
-
- public function getText()
- {
- if (strlen($this->action_text)) {
- return $this->action_text;
- }
-
- if ($actionObj = $this->getActionObject()) {
- return $actionObj->getText();
- }
- }
-
- public function getActionObject()
- {
- $this->applyActionClass();
-
- return $this->asExtension($this->getActionClass());
- }
-
- public function getActionClass()
- {
- return $this->class_name;
- }
-}
diff --git a/plugins/rainlab/notify/models/RuleCondition.php b/plugins/rainlab/notify/models/RuleCondition.php
deleted file mode 100644
index 0282748..0000000
--- a/plugins/rainlab/notify/models/RuleCondition.php
+++ /dev/null
@@ -1,172 +0,0 @@
- [self::class, 'key' => 'rule_parent_id', 'delete' => true],
- ];
-
- public $belongsTo = [
- 'parent' => [self::class, 'key' => 'rule_parent_id'],
- 'notification_rule' => [NotificationRule::class, 'key'=>'rule_host_id']
- ];
-
- public function filterFields($fields, $context)
- {
- /*
- * Let the condition contribute
- */
- $this->getConditionObject()->setFormFields($fields);
- }
-
- /**
- * Extends this model with the condition class
- * @param string $class Class name
- * @return boolean
- */
- public function applyConditionClass($class = null)
- {
- if (!$class) {
- $class = $this->class_name;
- }
-
- if (!$class) {
- return false;
- }
-
- if (!$this->isClassExtendedWith($class)) {
- $this->extendClassWith($class);
- }
-
- $this->class_name = $class;
- return true;
- }
-
- public function beforeSave()
- {
- $this->setCustomData();
- }
-
- public function applyCustomData()
- {
- $this->setCustomData();
- $this->loadCustomData();
- }
-
- protected function loadCustomData()
- {
- $this->setRawAttributes((array) $this->getAttributes() + (array) $this->config_data, true);
- }
-
- protected function setCustomData()
- {
- /*
- * Let the condition contribute
- */
- $this->getConditionObject()->setCustomData($this);
-
- /*
- * Spin over each field and add it to config_data
- */
- $config = $this->getFieldConfig();
-
- if (!isset($config->fields)) {
- throw new SystemException('Condition class has no fields.');
- }
-
- $staticAttributes = ['condition_text'];
-
- $fieldAttributes = array_merge($staticAttributes, array_keys($config->fields));
-
- $dynamicAttributes = array_only($this->getAttributes(), $fieldAttributes);
-
- $this->config_data = $dynamicAttributes;
-
- $this->setRawAttributes(array_except($this->getAttributes(), $fieldAttributes));
- }
-
- public function afterFetch()
- {
- $this->applyConditionClass();
- $this->loadCustomData();
- }
-
- public function afterSave()
- {
- // Make sure that this record is removed from the DB after being removed from a rule
- $removedFromRule = $this->rule_parent_id === null && $this->getOriginal('rule_parent_id');
- if ($removedFromRule && !$this->notification_rule()->withDeferred(post('_session_key'))->exists()) {
- $this->delete();
- }
- }
-
- public function getText()
- {
- if (strlen($this->condition_text)) {
- return $this->condition_text;
- }
-
- if ($conditionObj = $this->getConditionObject()) {
- return $conditionObj->getText();
- }
- }
-
- public function isCompound()
- {
- return $this->getConditionObject() instanceof CompoundConditionInterface;
- }
-
- public function getConditionObject()
- {
- $this->applyConditionClass();
-
- return $this->asExtension($this->getConditionClass());
- }
-
- public function getConditionClass()
- {
- return $this->class_name;
- }
-
- public function getRootConditionClass()
- {
- return CompoundCondition::class;
- }
-}
diff --git a/plugins/rainlab/notify/models/notificationrule/columns.yaml b/plugins/rainlab/notify/models/notificationrule/columns.yaml
deleted file mode 100644
index 6da7d0f..0000000
--- a/plugins/rainlab/notify/models/notificationrule/columns.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# ===================================
-# Column Definitions
-# ===================================
-
-columns:
-
- name:
- label: rainlab.notify::lang.notifications.name
- searchable: true
-
- code:
- label: rainlab.notify::lang.notifications.code
- searchable: true
diff --git a/plugins/rainlab/notify/models/notificationrule/fields.yaml b/plugins/rainlab/notify/models/notificationrule/fields.yaml
deleted file mode 100644
index b0eec2a..0000000
--- a/plugins/rainlab/notify/models/notificationrule/fields.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-# ===================================
-# Field Definitions
-# ===================================
-
-fields:
- name:
- label: Name
- placeholder: New notification rule name
- attributes:
- autofocus: 1
-
- toolbar:
- type: partial
- path: form_toolbar
- cssClass: collapse-visible
-
-tabs:
- stretch: true
- cssClass: master-area
- paneCssClass:
- 'Actions': 'pane-compact'
-
- fields:
- rule_actions:
- type: RainLab\Notify\FormWidgets\ActionBuilder
- tab: Actions
-
- rule_conditions:
- type: RainLab\Notify\FormWidgets\ConditionBuilder
- tab: Conditions
-
- is_enabled:
- label: Active
- type: checkbox
- tab: Settings
- default: true
-
- description:
- label: Description
- type: textarea
- size: tiny
- tab: Settings
-
- code:
- label: API Code
- span: auto
- tab: Settings
diff --git a/plugins/rainlab/notify/models/ruleaction/columns.yaml b/plugins/rainlab/notify/models/ruleaction/columns.yaml
deleted file mode 100644
index b11160b..0000000
--- a/plugins/rainlab/notify/models/ruleaction/columns.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-# ===================================
-# List Column Definitions
-# ===================================
-
-columns:
- id:
- label: ID
- searchable: true
diff --git a/plugins/rainlab/notify/models/ruleaction/fields.yaml b/plugins/rainlab/notify/models/ruleaction/fields.yaml
deleted file mode 100644
index c611f31..0000000
--- a/plugins/rainlab/notify/models/ruleaction/fields.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-# ===================================
-# Form Field Definitions
-# ===================================
-
-fields:
- id:
- label: ID
- disabled: true
diff --git a/plugins/rainlab/notify/notifyrules/ExecutionContextCondition.php b/plugins/rainlab/notify/notifyrules/ExecutionContextCondition.php
deleted file mode 100644
index 32369ca..0000000
--- a/plugins/rainlab/notify/notifyrules/ExecutionContextCondition.php
+++ /dev/null
@@ -1,136 +0,0 @@
- 'is',
- 'is_not' => 'is not',
- ];
-
- public function getName()
- {
- return 'Event is triggered from environment';
- }
-
- public function getTitle()
- {
- return 'Execution context';
- }
-
- public function getText()
- {
- $host = $this->host;
- $value = $host->value;
- $attribute = $host->subcondition;
- $subconditions = $this->getSubconditionOptions();
-
- $result = array_get($subconditions, $attribute, 'Execution context');
- $result .= ' '.array_get($this->operators, $host->operator, $host->operator).' ';
-
- if ($attribute == 'locale' || $attribute == 'environment') {
- $result .= strtolower($value) ?: '?';
- }
- elseif ($value) {
- $options = $this->getValueOptions();
- $result .= strtolower(array_get($options, $value));
- }
- else {
- $result .= '?';
- }
-
- return $result;
- }
-
- /**
- * Returns a title to use for grouping subconditions
- * in the Create Condition drop-down menu
- */
- public function getGroupingTitle()
- {
- return 'Execution context';
- }
-
- public function listSubconditions()
- {
- return array_flip($this->getSubconditionOptions());
- }
-
- public function initConfigData($host)
- {
- $host->operator = 'is';
- }
-
- public function setFormFields($fields)
- {
- $attribute = $fields->subcondition->value;
-
- if ($attribute == 'locale' || $attribute == 'environment') {
- $fields->value->type = 'text';
- }
- else {
- $fields->value->type = 'dropdown';
- }
- }
-
- public function getValueOptions()
- {
- $attribute = $this->host->subcondition;
- $result = [];
-
- if ($attribute == 'context') {
- $result = [
- 'backend' => 'Back-end area',
- 'front' => 'Front-end website',
- 'console' => 'Command line interface',
- ];
- }
-
- if ($attribute == 'theme') {
- foreach (Theme::all() as $theme) {
- $result[$theme->getDirName()] = $theme->getDirName();
- }
- }
-
- return $result;
- }
-
- public function getSubconditionOptions()
- {
- return [
- 'environment' => 'Application environment',
- 'context' => 'Request context',
- 'theme' => 'Active theme',
- 'locale' => 'Visitor locale',
- ];
- }
-
- public function getOperatorOptions()
- {
- return $this->operators;
- }
-
- /**
- * Checks whether the condition is TRUE for specified parameters
- * @param array $params
- * @return bool
- */
- public function isTrue(&$params)
- {
- $hostObj = $this->host;
- $attribute = $hostObj->subcondition;
-
- $conditionValue = $hostObj->value;
- $conditionValue = trim(mb_strtolower($conditionValue));
-
- if ($attribute == 'locale') {
- return array_get($params, 'appLocale') == $conditionValue;
- } else if ($attribute === 'environment') {
- return $conditionValue === \App::environment();
- }
-
- return false;
- }
-}
diff --git a/plugins/rainlab/notify/notifyrules/SaveDatabaseAction.php b/plugins/rainlab/notify/notifyrules/SaveDatabaseAction.php
deleted file mode 100644
index 44e8415..0000000
--- a/plugins/rainlab/notify/notifyrules/SaveDatabaseAction.php
+++ /dev/null
@@ -1,125 +0,0 @@
- 'Store in database',
- 'description' => 'Log event data in the notifications activity log',
- 'icon' => 'icon-database'
- ];
- }
-
- public function defineFormFields()
- {
- return 'fields.yaml';
- }
-
- public function getText()
- {
- if ($this->host->related_object) {
- $label = array_get($this->getRelatedObjectOptions(), $this->host->related_object);
-
- return 'Log event in the '.$label.' log';
- }
-
- return parent::getText();
- }
-
- /**
- * Triggers this action.
- * @param array $params
- * @return void
- */
- public function triggerAction($params)
- {
- if (
- (!$definition = array_get($this->tableDefinitions, $this->host->related_object)) ||
- (!$param = array_get($definition, 'param', 'user')) ||
- (!$value = array_get($params, $param))
- ) {
- throw new ApplicationException('Error evaluating the save database action: the related object is not found in the action parameters.');
- }
-
- if (!$value instanceof EloquentModel) {
- // @todo Perhaps value is an ID or a model array,
- // look up model $definition[class] from ID ...
- $model = array_get($definition,'class', User::class);
- $value = $model::find($value);
-
- }
-
- $rule = $this->host->notification_rule;
- $relation = array_get($definition, 'relation', 'notifications');
-
- $value->$relation()->create([
- 'id' => Uuid::uuid4()->toString(),
- 'event_type' => $rule->getEventClass(),
- 'icon' => $this->host->icon,
- 'type' => $this->host->type,
- 'body' => $this->host->body,
- 'data' => $this->getData($params),
- 'read_at' => null,
- ]);
- }
-
- /**
- * Get the data for the notification.
- *
- * @param array $notifiable
- * @return array
- */
- protected function getData($params)
- {
- // This should check for params that cannot be jsonable.
- return $params;
- }
-
- public function getRelatedObjectOptions()
- {
- $result = [];
-
- foreach ($this->tableDefinitions as $key => $definition) {
- $result[$key] = array_get($definition, 'label');
- }
-
- return $result;
- }
-
- public function getTableDefinitions()
- {
- return $this->tableDefinitions;
- }
-
- public function addTableDefinition($options)
- {
- if (!$className = array_get($options, 'class')) {
- throw new ApplicationException('Missing class name from table definition.');
- }
-
- $options = array_merge([
- 'label' => 'Undefined table',
- 'class' => null,
- 'param' => null,
- 'relation' => 'notifications',
- ], $options);
-
- $keyName = $className . '@' . array_get($options, 'relation');
-
- $this->tableDefinitions[$keyName] = $options;
- }
-}
diff --git a/plugins/rainlab/notify/notifyrules/SendMailTemplateAction.php b/plugins/rainlab/notify/notifyrules/SendMailTemplateAction.php
deleted file mode 100644
index 231c9c9..0000000
--- a/plugins/rainlab/notify/notifyrules/SendMailTemplateAction.php
+++ /dev/null
@@ -1,223 +0,0 @@
- 'System default',
- 'user' => 'User email address (if applicable)',
- 'sender' => 'Sender user email address (if applicable)',
- 'admin' => 'Back-end administrators',
- 'custom' => 'Specific email address',
- ];
-
- /**
- * Returns information about this event, including name and description.
- */
- public function actionDetails()
- {
- return [
- 'name' => 'Compose a mail message',
- 'description' => 'Send a message to a recipient',
- 'icon' => 'icon-envelope'
- ];
- }
-
- /**
- * Triggers this action.
- * @param array $params
- * @return void
- */
- public function triggerAction($params)
- {
- if($this->host->send_to_mode == 'user' && $params['user']) {
- if(!$params['user']['email_verified'])
- return;
- }
- $template = $this->host->mail_template;
-
- $recipient = $this->getRecipientAddress($params);
-
- $replyTo = $this->getReplyToAddress($params);
-
- if (!$recipient || !$template) {
- throw new ApplicationException('Missing valid recipient or mail template');
- }
-
- Mail::sendTo($recipient, $template, $params, function($message) use ($replyTo) {
- if ($replyTo) {
- $message->replyTo($replyTo);
- }
- });
- }
-
- /**
- * Field configuration for the action.
- */
- public function defineFormFields()
- {
- return 'fields.yaml';
- }
-
- /**
- * Defines validation rules for the custom fields.
- * @return array
- */
- public function defineValidationRules()
- {
- return [
- 'mail_template' => 'required',
- 'send_to_mode' => 'required',
- ];
- }
-
- public function getTitle()
- {
- if ($this->isAdminMode()) {
- return 'Compose mail to administrators';
- }
-
- return parent::getTitle();
- }
-
- public function getActionIcon()
- {
- if ($this->isAdminMode()) {
- return 'icon-envelope-square';
- }
-
- return parent::getActionIcon();
- }
-
- public function getText()
- {
- $hostObj = $this->host;
-
- $recipient = array_get($this->recipientModes, $hostObj->send_to_mode);
-
- if ($this->isAdminMode()) {
- if ($groupId = $this->host->send_to_admin) {
- if ($group = AdminGroupModel::find($groupId)) {
- $adminText = $group->name;
- }
- else {
- $adminText = '?';
- }
-
- $adminText .= ' admin group';
- }
- else {
- $adminText = 'all admins';
- }
- return sprintf(
- 'Send a message to %s using template %s',
- $adminText,
- $hostObj->mail_template
- );
- }
-
- if ($hostObj->mail_template) {
- return sprintf(
- 'Send a message to %s using template %s',
- mb_strtolower($recipient),
- $hostObj->mail_template
- );
- }
-
- return parent::getText();
- }
-
- public function getSendToAdminOptions()
- {
- $options = ['' => '- All administrators -'];
-
- $groups = AdminGroupModel::lists('name', 'id');
-
- return $options + $groups;
- }
-
- public function getSendToModeOptions()
- {
- $modes = $this->recipientModes;
-
- unset($modes['system']);
-
- return $modes;
- }
-
- public function getReplyToModeOptions()
- {
- $modes = $this->recipientModes;
-
- unset($modes['admin']);
-
- return $modes;
- }
-
- public function getMailTemplateOptions()
- {
- $codes = array_keys(MailTemplate::listAllTemplates());
- $result = array_combine($codes, $codes);
- return $result;
- }
-
- protected function getReplyToAddress($params)
- {
- $mode = $this->host->reply_to_mode;
-
- if ($mode == 'custom') {
- return $this->host->reply_to_custom;
- }
-
- if ($mode == 'user' || $mode == 'sender') {
- $obj = array_get($params, $mode);
- return $obj->email;
- }
- }
-
- protected function getRecipientAddress($params)
- {
- $mode = $this->host->send_to_mode;
-
- if ($mode == 'custom') {
- return $this->host->send_to_custom;
- }
-
- if ($mode == 'system') {
- $name = Config::get('mail.from.name', 'Your Site');
- $address = Config::get('mail.from.address', 'admin@domain.tld');
- return [$address => $name];
- }
-
- if ($mode == 'admin') {
- if ($groupId = $this->host->send_to_admin) {
- if (!$group = AdminGroupModel::find($groupId)) {
- throw new ApplicationException('Unable to find admin group with ID: '.$groupId);
- }
-
- return $group->users->lists('full_name', 'email');
- }
- else {
- return AdminUserModel::all()->lists('full_name', 'email');
- }
- }
-
- if ($mode == 'user' || $mode == 'sender') {
- return array_get($params, $mode);
- }
- }
-
- protected function isAdminMode()
- {
- return $this->host->send_to_mode == 'admin';
- }
-}
diff --git a/plugins/rainlab/notify/notifyrules/executioncontextcondition/fields.yaml b/plugins/rainlab/notify/notifyrules/executioncontextcondition/fields.yaml
deleted file mode 100644
index 9981f87..0000000
--- a/plugins/rainlab/notify/notifyrules/executioncontextcondition/fields.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-# ===================================
-# Field Definitions
-# ===================================
-
-fields:
-
- subcondition:
- label: Attribute
- span: auto
- type: dropdown
-
- operator:
- label: Operator
- span: auto
- type: dropdown
- dependsOn: subcondition
-
- value:
- label: Value
- dependsOn: [subcondition, operator]
- type: dropdown
diff --git a/plugins/rainlab/notify/notifyrules/savedatabaseaction/fields.yaml b/plugins/rainlab/notify/notifyrules/savedatabaseaction/fields.yaml
deleted file mode 100644
index 77c144f..0000000
--- a/plugins/rainlab/notify/notifyrules/savedatabaseaction/fields.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-# ===================================
-# Field Definitions
-# ===================================
-
-fields:
- related_object:
- label: Related object
- type: dropdown
diff --git a/plugins/rainlab/notify/notifyrules/sendmailtemplateaction/fields.yaml b/plugins/rainlab/notify/notifyrules/sendmailtemplateaction/fields.yaml
deleted file mode 100644
index 13aa548..0000000
--- a/plugins/rainlab/notify/notifyrules/sendmailtemplateaction/fields.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-# ===================================
-# Field Definitions
-# ===================================
-
-fields:
- mail_template:
- label: Mail template
- type: dropdown
- placeholder: Select template
-
- send_to_mode:
- label: Send to
- type: radio
- span: left
-
- send_to_custom:
- cssClass: radio-align
- trigger:
- action: show
- field: send_to_mode
- condition: value[custom]
-
- send_to_admin:
- label: Send to admin group
- span: right
- type: dropdown
- trigger:
- action: show
- field: send_to_mode
- condition: value[admin]
-
- reply_to_mode:
- label: Reply-to address
- type: radio
- span: left
-
- reply_to_custom:
- cssClass: radio-align
- trigger:
- action: show
- field: reply_to_mode
- condition: value[custom]
diff --git a/plugins/rainlab/notify/updates/create_notification_rules_table.php b/plugins/rainlab/notify/updates/create_notification_rules_table.php
deleted file mode 100644
index 2bcc6b0..0000000
--- a/plugins/rainlab/notify/updates/create_notification_rules_table.php
+++ /dev/null
@@ -1,29 +0,0 @@
-engine = 'InnoDB';
- $table->increments('id');
- $table->string('name')->nullable();
- $table->string('code')->index()->nullable();
- $table->string('class_name')->nullable();
- $table->text('description')->nullable();
- $table->mediumText('config_data')->nullable();
- $table->mediumText('condition_data')->nullable();
- $table->boolean('is_enabled')->default(0);
- $table->boolean('is_custom')->default(1);
- $table->timestamps();
- });
- }
-
- public function down()
- {
- Schema::dropIfExists('rainlab_notify_notification_rules');
- }
-}
diff --git a/plugins/rainlab/notify/updates/create_notifications_table.php b/plugins/rainlab/notify/updates/create_notifications_table.php
deleted file mode 100644
index 4c73bb4..0000000
--- a/plugins/rainlab/notify/updates/create_notifications_table.php
+++ /dev/null
@@ -1,28 +0,0 @@
-uuid('id')->primary();
- $table->string('event_type');
- $table->morphs('notifiable');
- $table->string('icon')->nullable();
- $table->string('type')->nullable();
- $table->text('body')->nullable();
- $table->mediumText('data');
- $table->timestamp('read_at')->nullable();
- $table->timestamps();
- });
- }
-
- public function down()
- {
- Schema::dropIfExists('rainlab_notify_notifications');
- }
-}
diff --git a/plugins/rainlab/notify/updates/create_rule_actions_table.php b/plugins/rainlab/notify/updates/create_rule_actions_table.php
deleted file mode 100644
index af89e41..0000000
--- a/plugins/rainlab/notify/updates/create_rule_actions_table.php
+++ /dev/null
@@ -1,25 +0,0 @@
-engine = 'InnoDB';
- $table->increments('id');
- $table->string('class_name')->nullable();
- $table->mediumText('config_data')->nullable();
- $table->integer('rule_host_id')->unsigned()->nullable()->index();
- $table->timestamps();
- });
- }
-
- public function down()
- {
- Schema::dropIfExists('rainlab_notify_rule_actions');
- }
-}
diff --git a/plugins/rainlab/notify/updates/create_rule_conditions_table.php b/plugins/rainlab/notify/updates/create_rule_conditions_table.php
deleted file mode 100644
index 4a0211e..0000000
--- a/plugins/rainlab/notify/updates/create_rule_conditions_table.php
+++ /dev/null
@@ -1,29 +0,0 @@
-engine = 'InnoDB';
- $table->increments('id');
- $table->string('class_name')->nullable();
- $table->mediumText('config_data')->nullable();
- $table->string('condition_control_type', 100)->nullable();
- $table->string('rule_host_type', 100)->nullable();
- $table->integer('rule_host_id')->unsigned()->nullable()->index();
- $table->integer('rule_parent_id')->unsigned()->nullable()->index();
- $table->index(['rule_host_id', 'rule_host_type'], 'host_rule_id_type');
- $table->timestamps();
- });
- }
-
- public function down()
- {
- Schema::dropIfExists('rainlab_notify_rule_conditions');
- }
-}
diff --git a/plugins/rainlab/notify/updates/version.yaml b/plugins/rainlab/notify/updates/version.yaml
deleted file mode 100644
index 2c184f4..0000000
--- a/plugins/rainlab/notify/updates/version.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-v1.0.1:
- - First version of Notify
- - create_notifications_table.php
- - create_notification_rules_table.php
- - create_rule_conditions_table.php
- - create_rule_actions_table.php
-v1.0.2: Fixes crashing bug.
-v1.0.3: Added Turkish & Russian translations, various bug fixes.
-v1.1.0: Fixes support for October CMS 2.0
diff --git a/plugins/rainlab/user/.gitignore b/plugins/rainlab/user/.gitignore
new file mode 100644
index 0000000..77bed77
--- /dev/null
+++ b/plugins/rainlab/user/.gitignore
@@ -0,0 +1,3 @@
+.phpunit.result.cache
+composer.lock
+vendor
diff --git a/plugins/rainlab/user/Plugin.php b/plugins/rainlab/user/Plugin.php
index 8feafec..0152481 100644
--- a/plugins/rainlab/user/Plugin.php
+++ b/plugins/rainlab/user/Plugin.php
@@ -2,7 +2,6 @@
use App;
use Auth;
-use Carbon\Carbon;
use Event;
use Backend;
use System\Classes\PluginBase;
@@ -33,7 +32,7 @@ class Plugin extends PluginBase
public function register()
{
$alias = AliasLoader::getInstance();
- $alias->alias('Auth', 'RainLab\User\Facades\Auth');
+ $alias->alias('Auth', \RainLab\User\Facades\Auth::class);
App::singleton('user.auth', function () {
return \RainLab\User\Classes\AuthManager::instance();
@@ -70,8 +69,8 @@ class Plugin extends PluginBase
public function registerComponents()
{
return [
- \RainLab\User\Components\Session::class => 'session',
- \RainLab\User\Components\Account::class => 'account',
+ \RainLab\User\Components\Session::class => 'session',
+ \RainLab\User\Components\Account::class => 'account',
\RainLab\User\Components\ResetPassword::class => 'resetPassword'
];
}
@@ -116,12 +115,12 @@ class Plugin extends PluginBase
'url' => Backend::url('rainlab/user/users'),
'permissions' => ['rainlab.users.access_users']
],
- // 'usergroups' => [
- // 'label' => 'rainlab.user::lang.groups.menu_label',
- // 'icon' => 'icon-users',
- // 'url' => Backend::url('rainlab/user/usergroups'),
- // 'permissions' => ['rainlab.users.access_groups']
- // ]
+ 'usergroups' => [
+ 'label' => 'rainlab.user::lang.groups.menu_label',
+ 'icon' => 'icon-users',
+ 'url' => Backend::url('rainlab/user/usergroups'),
+ 'permissions' => ['rainlab.users.access_groups']
+ ]
]
]
];
@@ -134,7 +133,7 @@ class Plugin extends PluginBase
'label' => 'rainlab.user::lang.settings.menu_label',
'description' => 'rainlab.user::lang.settings.menu_description',
'category' => SettingsManager::CATEGORY_USERS,
- 'icon' => 'icon-cog',
+ 'icon' => class_exists('System') ? 'octo-icon-user-actions-key' : 'icon-cog',
'class' => 'RainLab\User\Models\Settings',
'order' => 500,
'permissions' => ['rainlab.users.access_settings']
@@ -191,28 +190,4 @@ class Plugin extends PluginBase
]);
});
}
-
- public function registerListColumnTypes()
- {
- return [
- 'email_verified' => [$this, 'emailVerified'],
- 'phone_verified' => [$this, 'phoneVerified'],
- ];
- }
-
- public function emailVerified($value, $column, $record){
- switch ($value){
- case 0 : return 'Not verified';
- case 1 : return 'Verified';
- default : return $value;
- }
- }
-
- public function phoneVerified($value, $column, $record){
- switch ($value){
- case 0 : return 'Not verified';
- case 1 : return 'Verified';
- default : return $value;
- }
- }
}
diff --git a/plugins/rainlab/user/README.md b/plugins/rainlab/user/README.md
index 80d3596..dd4604a 100644
--- a/plugins/rainlab/user/README.md
+++ b/plugins/rainlab/user/README.md
@@ -1,14 +1,25 @@
# Front-end user plugin
-[](https://github.com/rainlab/user-plugin/actions)
-[](https://github.com/rainlab/user-plugin/blob/master/LICENCE.md)
-
Front-end user management for October CMS.
## Requirements
This plugin requires the [Ajax Framework](https://octobercms.com/docs/cms/ajax) to be included in your layout/page in order to handle form requests.
+## Installation Instructions
+
+Run the following to install this plugin:
+
+```bash
+php artisan plugin:install RainLab.User
+```
+
+To uninstall this plugin:
+
+```bash
+php artisan plugin:remove RainLab.User
+```
+
## Managing users
Users are managed on the Users tab found in the back-end. Each user provides minimal data fields - **Name**, **Surname**, **Email** and **Password**. The Name can represent either the person's first name or their full name, making the Surname field optional, depending on the complexity of your site.
@@ -47,7 +58,17 @@ As a security precaution, you may restrict users from having sessions across mul
#### Notifications
-When a user is first activated -- either by registration, email confirmation or administrator approval -- they are sent a welcome email. To disable the welcome email, select "Do not send a notification" from the **Welcome mail template** dropdown. The default message template used is `rainlab.user::mail.welcome` and you can customize this by selecting **Mail > Mail Templates** from the settings menu.
+This feature is implemented by the Notify plugin. How to use this feature:
+
+- Install the **RainLab.Notify** plugin
+- Navigate to **Settings > Notification** rules
+- Click **New notification rule**
+- Select **User > Activated**
+- Click **Add action**
+- Select **Compose a mail message**
+- Select **User email address** for the **Send to** field
+- Here you may select the Mail template previously defined in the user settings.
+- Click **Save**
## Extended features
diff --git a/plugins/rainlab/user/assets/js/bulk-actions.js b/plugins/rainlab/user/assets/js/bulk-actions.js
index d0e2089..69885f9 100644
--- a/plugins/rainlab/user/assets/js/bulk-actions.js
+++ b/plugins/rainlab/user/assets/js/bulk-actions.js
@@ -1,6 +1,6 @@
/*
* Bulk actions plugin
- *
+ *
* Data attributes:
* - data-control="bulk-actions" - enables the plugin on an element
*
@@ -53,12 +53,12 @@
}
BulkActions.prototype.setActiveItem = function($el) {
- this.$toggleBtn.blur()
- this.activeAction = $el.data('action')
- this.$primaryBtn.text($el.text())
- this.$primaryBtn.attr('class', this.baseCss)
- this.$primaryBtn.addClass($el.attr('class'))
- this.$primaryBtn.data('request-confirm', $el.data('confirm'))
+ this.$toggleBtn.blur();
+ this.activeAction = $el.data('action');
+ this.$primaryBtn.text($el.text());
+ this.$primaryBtn.attr('class', this.baseCss);
+ this.$primaryBtn.addClass($el.attr('class')).removeClass('dropdown-item');
+ this.$primaryBtn.data('request-confirm', $el.data('confirm'));
}
// BULK ACTIONS PLUGIN DEFINITION
diff --git a/plugins/rainlab/user/classes/AuthManager.php b/plugins/rainlab/user/classes/AuthManager.php
index 269955c..8cf5386 100644
--- a/plugins/rainlab/user/classes/AuthManager.php
+++ b/plugins/rainlab/user/classes/AuthManager.php
@@ -1,5 +1,6 @@
withTrashed();
+
+ // Extensibility
+ Event::fire('rainlab.user.extendUserAuthQuery', [$query]);
}
/**
@@ -43,6 +47,25 @@ class AuthManager extends RainAuthManager
return parent::register($credentials, $activate, $autoLogin);
}
+ /**
+ * findUserByEmail finds a user by the email value, which includes
+ * deactivated (trashed) user records.
+ * @param string $email
+ * @return Authenticatable|null
+ */
+ public function findUserByEmail($email)
+ {
+ if (!$email) {
+ return null;
+ }
+
+ $query = $this->createUserModelQuery();
+
+ $user = $query->where('email', $email)->first();
+
+ return $this->validateUserModel($user) ? $user : null;
+ }
+
//
// Guest users
//
@@ -60,10 +83,11 @@ class AuthManager extends RainAuthManager
{
$query = $this->createUserModelQuery();
- return $user = $query
+ return $query
->where('email', $email)
->where('is_guest', 1)
- ->first();
+ ->first()
+ ;
}
/**
diff --git a/plugins/rainlab/user/components/Account.php b/plugins/rainlab/user/components/Account.php
index cb3cd91..28b08d8 100644
--- a/plugins/rainlab/user/components/Account.php
+++ b/plugins/rainlab/user/components/Account.php
@@ -17,8 +17,6 @@ use Cms\Classes\ComponentBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Models\Settings as UserSettings;
use Exception;
-use Throwable;
-use TPS\Birzha\Classes\SMS;
/**
* Account component
@@ -28,11 +26,6 @@ use TPS\Birzha\Classes\SMS;
*/
class Account extends ComponentBase
{
- /**
- * Validation messages
- */
- public $accountValidationMsgs;
-
public function componentDetails()
{
return [
@@ -56,6 +49,12 @@ class Account extends ComponentBase
'type' => 'string',
'default' => 'code'
],
+ 'activationPage' => [
+ 'title' => /* Activation Page */'rainlab.user::lang.account.activation_page',
+ 'description' => /* Select a page to use for activating the user account */'rainlab.user::lang.account.activation_page_comment',
+ 'type' => 'dropdown',
+ 'default' => ''
+ ],
'forceSecure' => [
'title' => /*Force secure protocol*/'rainlab.user::lang.account.force_secure',
'description' => /*Always redirect the URL with the HTTPS schema.*/'rainlab.user::lang.account.force_secure_desc',
@@ -68,19 +67,28 @@ class Account extends ComponentBase
'type' => 'checkbox',
'default' => 0
],
- 'view' => [
- 'title' => 'View',
- 'description' => 'Choose view type',
- 'type' => 'dropdown',
- 'options' => ['signin','signup','profile'],
- 'default' => 'signin'
- ]
];
}
+ /**
+ * getRedirectOptions
+ */
public function getRedirectOptions()
{
- return [''=>'- refresh page -', '0' => '- no redirect -'] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
+ return [
+ '' => '- refresh page -',
+ '0' => '- no redirect -'
+ ] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
+ }
+
+ /**
+ * getActivationPageOptions
+ */
+ public function getActivationPageOptions()
+ {
+ return [
+ '' => '- current page -',
+ ] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
/**
@@ -111,9 +119,9 @@ class Account extends ComponentBase
/*
* Activation code supplied
*/
- // if ($code = $this->activationCode()) {
- // $this->onActivate($code);
- // }
+ if ($code = $this->activationCode()) {
+ $this->onActivate($code);
+ }
$this->prepareVars();
}
@@ -177,6 +185,23 @@ class Account extends ComponentBase
return UserSettings::get('remember_login', UserSettings::REMEMBER_ALWAYS);
}
+ /**
+ * useRememberLogin returns true if persistent authentication should be used.
+ */
+ protected function useRememberLogin(): bool
+ {
+ switch ($this->rememberLoginMode()) {
+ case UserSettings::REMEMBER_ALWAYS:
+ return true;
+
+ case UserSettings::REMEMBER_NEVER:
+ return false;
+
+ case UserSettings::REMEMBER_ASK:
+ return (bool) post('remember', false);
+ }
+ }
+
/**
* Looks for the activation code from the URL parameter. If nothing
* is found, the GET parameter 'activate' is used instead.
@@ -213,7 +238,7 @@ class Account extends ComponentBase
? 'required|between:2,255'
: 'required|email|between:6,255';
- $rules['password'] = 'required|between:4,255';
+ $rules['password'] = 'required|between:' . UserModel::getMinPasswordLength() . ',255';
if (!array_key_exists('login', $data)) {
$data['login'] = post('username', post('email'));
@@ -221,7 +246,13 @@ class Account extends ComponentBase
$data['login'] = trim($data['login']);
- $validation = Validator::make($data, $rules);
+ $validation = Validator::make(
+ $data,
+ $rules,
+ $this->getValidatorMessages(),
+ $this->getCustomAttributes()
+ );
+
if ($validation->fails()) {
throw new ValidationException($validation);
}
@@ -230,31 +261,16 @@ class Account extends ComponentBase
* Authenticate user
*/
$credentials = [
- 'login' => array_get($data, 'dial_code') . array_get($data, 'login'),
+ 'login' => array_get($data, 'login'),
'password' => array_get($data, 'password')
];
- /*
- * Login remember mode
- */
- switch ($this->rememberLoginMode()) {
- case UserSettings::REMEMBER_ALWAYS:
- $remember = true;
- break;
- case UserSettings::REMEMBER_NEVER:
- $remember = false;
- break;
- case UserSettings::REMEMBER_ASK:
- $remember = (bool) array_get($data, 'remember', false);
- break;
- }
-
Event::fire('rainlab.user.beforeAuthenticate', [$this, $credentials]);
- $user = Auth::authenticate($credentials, $remember);
+ $user = Auth::authenticate($credentials, $this->useRememberLogin());
if ($user->isBanned()) {
Auth::logout();
- throw new AuthException(/*Sorry, this user is currently not activated. Please contact us for further assistance.*/'rainlab.user::lang.account.banned');
+ throw new AuthException(Lang::get(/*Sorry, this user is currently not activated. Please contact us for further assistance.*/'rainlab.user::lang.account.banned'));
}
/*
@@ -272,12 +288,7 @@ class Account extends ComponentBase
}
}
catch (Exception $ex) {
- if ($ex instanceof AuthException) {
- throw new ValidationException(['no_user' => trans('validation.no_user')]);
- }
-
- // if (Request::ajax()) throw $ex;
- if (Request::ajax()) info($ex);
+ if (Request::ajax()) throw $ex;
else Flash::error($ex->getMessage());
}
}
@@ -305,27 +316,19 @@ class Account extends ComponentBase
$data['password_confirmation'] = post('password');
}
- $rules = array_merge((new UserModel)->rules, [
- 'username' => [
- 'required',
- 'numeric',
- 'unique' => function($attribute, $value, $fail) use($data) {
- $u = UserModel::where('username', $data['dial_code'] . $value)->first();
- if(!is_null($u)) $fail(trans('validation.auth_profile.phone_number_unique'));
- }
- ],
- ]);
+ $rules = (new UserModel)->rules;
if ($this->loginAttribute() !== UserSettings::LOGIN_USERNAME) {
unset($rules['username']);
}
- $validation = Validator::make($data, $rules, [
- 'username.required' => trans('validation.auth_profile.phone_number_required'),
- 'username.numeric' => trans('validation.auth_profile.phone_number_numeric'),
- 'username.digits_between' => trans('validation.auth_profile.phone_number_digits_between'),
- 'username.unique' => trans('validation.auth_profile.phone_number_unique'),
- ]);
+ $validation = Validator::make(
+ $data,
+ $rules,
+ $this->getValidatorMessages(),
+ $this->getCustomAttributes()
+ );
+
if ($validation->fails()) {
throw new ValidationException($validation);
}
@@ -346,9 +349,6 @@ class Account extends ComponentBase
$automaticActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_AUTO;
$userActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_USER;
$adminActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_ADMIN;
- // $user = Auth::register(array_merge($data, [
- // 'username' => $data['dial_code'] . $data['username']
- // ]), $automaticActivation);
$user = Auth::register($data, $automaticActivation);
Event::fire('rainlab.user.register', [$user, $data]);
@@ -357,12 +357,13 @@ class Account extends ComponentBase
* Activation is by the user, send the email
*/
if ($userActivation) {
-// $this->sendActivationEmail($user);
-//
-// Flash::success(Lang::get(/*An activation email has been sent to your email address.*/'rainlab.user::lang.account.activation_email_sent'));
- //todo open activation view
+ $this->sendActivationEmail($user);
+
+ Flash::success(Lang::get(/*An activation email has been sent to your email address.*/'rainlab.user::lang.account.activation_email_sent'));
}
+ $intended = false;
+
/*
* Activation is by the admin, show message
* For automatic email on account activation RainLab.Notify plugin is needed
@@ -375,17 +376,16 @@ class Account extends ComponentBase
* Automatically activated or not required, log the user in
*/
if ($automaticActivation || !$requireActivation) {
- Auth::login($user);
+ Auth::login($user, $this->useRememberLogin());
+ $intended = true;
}
/*
* Redirect to the intended page after successful sign in
*/
- // if ($redirect = $this->makeRedirection(true)) {
- // return $redirect;
- // }
-
- return \Redirect::to('/profile');
+ if ($redirect = $this->makeRedirection($intended)) {
+ return $redirect;
+ }
}
catch (Exception $ex) {
if (Request::ajax()) throw $ex;
@@ -393,108 +393,6 @@ class Account extends ComponentBase
}
}
- /**
- * Send sms with 6 digits code to user
- */
- public function onSendSmsCode()
- {
- try {
- if($this->user()->dial_code == '+993' && !$this->user()->phone_verified) {
- $code = random_int(1000, 9999);
-
- $result = SMS::send(str_replace(array('+', ' ', '(' , ')', '-'), '', $this->user()->username), $code);
- // $result = 0;
- \Log::info('send sms result');
- \Log::info($result);
-
- switch ($result) {
- case 0:
- $this->user()->phone_activation_code = $code;
- $this->user()->save();
- \Log::info('case 0');
- break;
- case 1:
- return \Redirect::to('/error');
- \Log::info('case 1');
- break;
-
- default:
- return \Redirect::to('/error');
- \Log::info('case default');
- break;
- }
- }
- } catch(Throwable $th) {
- \Log::info($th);
- return \Redirect::to('/error');
- }
-
- }
-
- /**
- * Check SMS code sent by user
- */
- public function onCheckSmsCode()
- {
- $data = post();
-
- $validator = \Validator::make($data, [
- 'sms_code' => 'required|digits:4',
- ]);
- if($validator->fails()) {
- throw new ValidationException($validator);
- }
-
- if($this->user()->phone_activation_code == $data['sms_code']) {
- $this->user()->phone_verified = true;
- $this->user()->phone_activation_code = null;
- $this->user()->save();
-
- Flash::success(Lang::get('rainlab.user::lang.account.phone_verified_message'));
-
- return \Redirect::to('profile');
- } else {
- Flash::error(Lang::get('rainlab.user::lang.account.phone_verification_code_invalid'));
-
- return \Redirect::to('profile');
- }
- }
-
- /**
- * Send email with the verification link to the user
- */
- public function onSendEmailVerificationLink()
- {
- if(!$this->user()->email_verified) {
- $code = sha1(time());
- $vars = [
- 'verification_link' => $this->controller->pageUrl('kabinet/verify_email.htm', [
- 'id' => $this->user()->id, 'code' => $code
- ])
- ];
-
- try {
- \Mail::queue('tps.birzha::mail.' . app()->getLocale() . '.email_verify', $vars, function($message) {
- $message->to($this->user()->email, 'Birzha User');
- $message->subject(\Lang::get('rainlab.user::lang.account.email_verification'));
- });
- } catch(Throwable $th) {
- \Log::info($th);
-
- Flash::error('Ошибка. Неверный Email.');
-
- return \Redirect::to('profile');
- }
-
- $this->user()->email_activation_code = $code;
- $this->user()->save();
-
- Flash::success(\Lang::get('rainlab.user::lang.account.email_verification_check_message'));
-
- return \Redirect::to('profile');
- }
- }
-
/**
* Activate the user
* @param string $code Activation code
@@ -533,7 +431,7 @@ class Account extends ComponentBase
/*
* Sign in the user
*/
- Auth::login($user);
+ Auth::login($user, $this->useRememberLogin());
}
catch (Exception $ex) {
@@ -551,28 +449,7 @@ class Account extends ComponentBase
return;
}
- $data = Input::except(['username']);
-
- $rules = [
- 'email' => 'required|between:6,191|email',
- 'name' => 'required',
- 'surname' => 'required',
- // 'username' => 'required|digits_between:8,20|numeric',
- 'iu_company' => 'max:191',
- 'iu_about' => 'digits:6|numeric',
- ];
-
- $validation = Validator::make($data, $rules, [
- 'username.required' => trans('validation.auth_profile.phone_number_required'),
- 'username.numeric' => trans('validation.auth_profile.phone_number_numeric'),
- 'username.digits_between' => trans('validation.auth_profile.phone_number_digits_between'),
- 'username.unique' => trans('validation.auth_profile.phone_number_unique'),
- 'zip.digits' => trans('validation.auth_profile.iu_about_digits'),
- 'company.max' => trans('validation.auth_profile.iu_company_max'),
- ]);
- if ($validation->fails()) {
- throw new ValidationException($validation);
- }
+ $data = post();
if ($this->updateRequiresPassword()) {
if (!$user->checkHashValue('password', $data['password_current'])) {
@@ -584,11 +461,6 @@ class Account extends ComponentBase
$user->avatar = Input::file('avatar');
}
- if($user->email != $data['email']) {
- $user->email_verified = false;
- $user->save();
- }
-
$user->fill($data);
$user->save();
@@ -596,9 +468,14 @@ class Account extends ComponentBase
* Password has changed, reauthenticate the user
*/
if (array_key_exists('password', $data) && strlen($data['password'])) {
- Auth::login($user->reload(), true);
+ Auth::login($user->reload(), $this->useRememberLogin());
}
+ /*
+ * Update Event to hook into the plugins function
+ */
+ Event::fire('rainlab.user.update', [$user, $data]);
+
Flash::success(post('flash', Lang::get(/*Settings successfully saved!*/'rainlab.user::lang.account.success_saved')));
/*
@@ -728,12 +605,13 @@ class Account extends ComponentBase
{
$method = $intended ? 'intended' : 'to';
- $property = trim((string) $this->property('redirect'));
+ $property = post('redirect', $this->property('redirect'));
// No redirect
if ($property === '0') {
return;
}
+
// Refresh page
if ($property === '') {
return Redirect::refresh();
@@ -741,7 +619,7 @@ class Account extends ComponentBase
$redirectUrl = $this->pageUrl($property) ?: $property;
- if ($redirectUrl = post('redirect', $redirectUrl)) {
+ if ($redirectUrl) {
return Redirect::$method($redirectUrl);
}
}
@@ -776,4 +654,26 @@ class Account extends ComponentBase
return UserModel::isRegisterThrottled(Request::ip());
}
+
+ /**
+ * getValidatorMessages
+ */
+ protected function getValidatorMessages(): array
+ {
+ return (array) (new UserModel)->customMessages;
+ }
+
+ /**
+ * getCustomAttributes
+ */
+ protected function getCustomAttributes(): array
+ {
+ return [
+ 'login' => $this->loginAttributeLabel(),
+ 'password' => Lang::get('rainlab.user::lang.account.password'),
+ 'email' => Lang::get('rainlab.user::lang.account.email'),
+ 'username' => Lang::get('rainlab.user::lang.user.username'),
+ 'name' => Lang::get('rainlab.user::lang.account.full_name')
+ ];
+ }
}
diff --git a/plugins/rainlab/user/components/ResetPassword.php b/plugins/rainlab/user/components/ResetPassword.php
index 9d6e8fb..7966b10 100644
--- a/plugins/rainlab/user/components/ResetPassword.php
+++ b/plugins/rainlab/user/components/ResetPassword.php
@@ -6,11 +6,12 @@ use Mail;
use Validator;
use ValidationException;
use ApplicationException;
+use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\User as UserModel;
/**
- * Password reset workflow
+ * ResetPassword controls the password reset workflow
*
* When a user has forgotten their password, they are able to reset it using
* a unique token that, sent to their email address upon request.
@@ -33,10 +34,26 @@ class ResetPassword extends ComponentBase
'description' => /*The page URL parameter used for the reset code*/'rainlab.user::lang.reset_password.code_param_desc',
'type' => 'string',
'default' => 'code'
- ]
+ ],
+ 'resetPage' => [
+ 'title' => /* Reset Page */'rainlab.user::lang.account.reset_page',
+ 'description' => /* Select a page to use for resetting the account password */'rainlab.user::lang.account.reset_page_comment',
+ 'type' => 'dropdown',
+ 'default' => ''
+ ],
];
}
+ /**
+ * getResetPageOptions
+ */
+ public function getResetPageOptions()
+ {
+ return [
+ '' => '- current page -',
+ ] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
+ }
+
//
// Properties
//
@@ -74,8 +91,8 @@ class ResetPassword extends ComponentBase
throw new ValidationException($validation);
}
- $user = UserModel::findByEmail(post('email'));
- if (!$user || $user->is_guest) {
+ $user = Auth::findUserByEmail(post('email'));
+ if (!$user || $user->is_guest || $user->trashed()) {
throw new ApplicationException(Lang::get(/*A user was not found with the given credentials.*/'rainlab.user::lang.account.invalid_user'));
}
@@ -90,7 +107,7 @@ class ResetPassword extends ComponentBase
'code' => $code
];
- Mail::queue('tps.birzha::mail.' . app()->getLocale() . '.reset_password', $data, function($message) use ($user) {
+ Mail::send('rainlab.user::mail.restore', $data, function($message) use ($user) {
$message->to($user->email, $user->full_name);
});
}
@@ -133,6 +150,11 @@ class ResetPassword extends ComponentBase
if (!$user->attemptResetPassword($code, post('password'))) {
throw new ValidationException($errorFields);
}
+
+ // Check needed for compatibility with legacy systems
+ if (method_exists(\RainLab\User\Classes\AuthManager::class, 'clearThrottleForUserId')) {
+ Auth::clearThrottleForUserId($user->id);
+ }
}
//
@@ -140,7 +162,7 @@ class ResetPassword extends ComponentBase
//
/**
- * Returns a link used to reset the user account.
+ * makeResetUrl returns a link used to reset the user account.
* @return string
*/
protected function makeResetUrl($code)
@@ -149,10 +171,14 @@ class ResetPassword extends ComponentBase
$this->property('paramCode') => $code
];
+ // Locate the current page
+ $url = '';
+
if ($pageName = $this->property('resetPage')) {
$url = $this->pageUrl($pageName, $params);
}
- else {
+
+ if (!$url) {
$url = $this->currentPageUrl($params);
}
diff --git a/plugins/rainlab/user/components/Session.php b/plugins/rainlab/user/components/Session.php
index 0236cfe..0b140af 100644
--- a/plugins/rainlab/user/components/Session.php
+++ b/plugins/rainlab/user/components/Session.php
@@ -5,15 +5,14 @@ use Auth;
use Event;
use Flash;
use Request;
-use Response;
use Redirect;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\UserGroup;
-use ValidationException;
+use SystemException;
/**
- * User session
+ * Session component
*
* This will inject the user object to every page and provide the ability for
* the user to sign out. This can also be used to restrict access to pages.
@@ -62,11 +61,17 @@ class Session extends ComponentBase
];
}
+ /**
+ * getRedirectOptions
+ */
public function getRedirectOptions()
{
return [''=>'- none -'] + Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName');
}
+ /**
+ * getAllowedUserGroupsOptions
+ */
public function getAllowedUserGroupsOptions()
{
return UserGroup::lists('name','code');
@@ -77,9 +82,12 @@ class Session extends ComponentBase
*/
public function init()
{
- if (Request::ajax() && !$this->checkUserSecurity()) {
- abort(403, 'Access denied');
- }
+ // Inject security logic pre-AJAX
+ $this->controller->bindEvent('page.init', function() {
+ if (Request::ajax() && ($redirect = $this->checkUserSecurityRedirect())) {
+ return ['X_OCTOBER_REDIRECT' => $redirect->getTargetUrl()];
+ }
+ });
}
/**
@@ -87,13 +95,8 @@ class Session extends ComponentBase
*/
public function onRun()
{
- if (!$this->checkUserSecurity()) {
- if (empty($this->property('redirect'))) {
- throw new \InvalidArgumentException('Redirect property is empty');
- }
-
- $redirectUrl = $this->controller->pageUrl($this->property('redirect'));
- return Redirect::guest($redirectUrl);
+ if ($redirect = $this->checkUserSecurityRedirect()) {
+ return $redirect;
}
$this->page['user'] = $this->user();
@@ -172,13 +175,31 @@ class Session extends ComponentBase
}
/**
- * Checks if the user can access this page based on the security rules
- * @return bool
+ * checkUserSecurityRedirect will return a redirect if the user cannot access the page.
*/
- protected function checkUserSecurity()
+ protected function checkUserSecurityRedirect()
+ {
+ // No security layer enabled
+ if ($this->checkUserSecurity()) {
+ return;
+ }
+
+ if (!$this->property('redirect')) {
+ throw new SystemException('Redirect property is empty on Session component.');
+ }
+
+ $redirectUrl = $this->controller->pageUrl($this->property('redirect'));
+
+ return Redirect::guest($redirectUrl);
+ }
+
+ /**
+ * checkUserSecurity checks if the user can access this page based on the security rules.
+ */
+ protected function checkUserSecurity(): bool
{
$allowedGroup = $this->property('security', self::ALLOW_ALL);
- $allowedUserGroups = $this->property('allowedUserGroups', []);
+ $allowedUserGroups = (array) $this->property('allowedUserGroups', []);
$isAuthenticated = Auth::check();
if ($isAuthenticated) {
diff --git a/plugins/rainlab/user/components/resetpassword/check.htm b/plugins/rainlab/user/components/resetpassword/check.htm
deleted file mode 100644
index f0472f3..0000000
--- a/plugins/rainlab/user/components/resetpassword/check.htm
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- {{ 'auth.password_reset_check'|_ }}
-
-
\ No newline at end of file
diff --git a/plugins/rainlab/user/components/resetpassword/complete.htm b/plugins/rainlab/user/components/resetpassword/complete.htm
index e625cd2..d0d0baa 100644
--- a/plugins/rainlab/user/components/resetpassword/complete.htm
+++ b/plugins/rainlab/user/components/resetpassword/complete.htm
@@ -1,14 +1 @@
-
-
- {{ 'auth.password_reset_complete'|_ }}
-
-
-
\ No newline at end of file
+
Password reset complete, you may now sign in.
\ No newline at end of file
diff --git a/plugins/rainlab/user/components/resetpassword/default.htm b/plugins/rainlab/user/components/resetpassword/default.htm
index 385dc70..b2eed57 100644
--- a/plugins/rainlab/user/components/resetpassword/default.htm
+++ b/plugins/rainlab/user/components/resetpassword/default.htm
@@ -1,12 +1,7 @@
-
-
\ No newline at end of file
diff --git a/plugins/rainlab/user/components/resetpassword/reset.htm b/plugins/rainlab/user/components/resetpassword/reset.htm
index 3626ca6..78c62da 100644
--- a/plugins/rainlab/user/components/resetpassword/reset.htm
+++ b/plugins/rainlab/user/components/resetpassword/reset.htm
@@ -1,22 +1,19 @@
-
-
- {{ 'account.new_password'|_ }}
+
+ Please check your email for the activation code.
+
\ No newline at end of file
diff --git a/plugins/tps/birzha/controllers/usersliders/update.htm b/plugins/tps/birzha/controllers/usersliders/update.htm
new file mode 100644
index 0000000..d6777f2
--- /dev/null
+++ b/plugins/tps/birzha/controllers/usersliders/update.htm
@@ -0,0 +1,54 @@
+
+