Issues (538)

programs/Set/AppSSESet.php (8 issues)

1
<?php
2
//-------------------------------------------------------------------------
3
// OVIDENTIA http://www.ovidentia.org
4
// Ovidentia is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2, or (at your option)
7
// any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
// See the GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17
// USA.
18
//-------------------------------------------------------------------------
19
/**
20
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
21
 * @copyright Copyright (c) 2022 by SI4YOU ({@link https://www.siforyou.com})
22
 */
23
namespace Capwelton\LibApp\Set;
24
25
26
use Capwelton\LibApp\Func_App;
27
use function Capwelton\LibOrm\ORM_UserField;
0 ignored issues
show
The function Capwelton\LibOrm\ORM_UserField was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
28
use function Capwelton\LibOrm\ORM_StringField;
0 ignored issues
show
The function Capwelton\LibOrm\ORM_StringField was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
29
use function Capwelton\LibOrm\ORM_IntField;
0 ignored issues
show
The function Capwelton\LibOrm\ORM_IntField was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
30
use function Capwelton\LibOrm\ORM_DatetimeField;
0 ignored issues
show
The function Capwelton\LibOrm\ORM_DatetimeField was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
31
32
/**
33
 * @property ORMUserField      $user
34
 * @property ORMStringField    $data
35
 * @property ORMIntField       $type
36
 * @property ORMDatetimeField  $deleteOn
37
 *
38
 * @method AppSSE                       get()
39
 * @method AppSSE                       request()
40
 * @method AppSSE[]|ORMMySqlIterator    select()
41
 * @method AppSSE                       newRecord()
42
 * @method Func_App App()
43
 */
44
class AppSSESet extends AppRecordSet
45
{
46
    /**
47
     * @param Func_App $App
48
     */
49
    public function __construct(Func_App $App)
50
    {
51
        parent::__construct($App);
52
53
        $App = $this->App();
0 ignored issues
show
The assignment to $App is dead and can be removed.
Loading history...
54
55
        $this->setPrimaryKey('id');
56
57
        $this->addFields(
58
            ORM_UserField('user'),
59
            ORM_StringField('data'),
60
            ORM_IntField('type'),
61
            ORM_DatetimeField('deleteOn')
62
        );
63
    }
64
    
65
    public function selectUserSSE($user = null)
66
    {
67
        if(!isset($user)){
68
            $App = $this->App();
69
            $user = $App->getCurrentUser();
70
        }
71
        
72
        return $this->select($this->user->is($user));
0 ignored issues
show
The call to Capwelton\LibApp\Set\AppSSESet::select() has too many arguments starting with $this->user->is($user). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
        return $this->/** @scrutinizer ignore-call */ select($this->user->is($user));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
73
    }
74
    
75
    /**
76
     * Construct the data payload that will be send by the SSE request
77
     * @param int $user         Get the SSE data associated to this specified user id
78
     * @param boolean $delete   If true, every SSE data will be deleted after being sent to avoid sending multiple time the same data
79
     * @return string
80
     */
81
    public function getSSEData($user, $delete = false)
82
    {
83
        $hasData = false;
84
        $sseData = '{';
85
        
86
        $userSSEReloads = $this->select($this->user->is($user)->_AND_($this->type->is(AppSSE::TYPE_RELOAD_SELECTOR)));
0 ignored issues
show
The call to Capwelton\LibApp\Set\AppSSESet::select() has too many arguments starting with $this->user->is($user)->...:TYPE_RELOAD_SELECTOR)). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
        /** @scrutinizer ignore-call */ $userSSEReloads = $this->select($this->user->is($user)->_AND_($this->type->is(AppSSE::TYPE_RELOAD_SELECTOR)));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
87
        $reloadSelectors = array();
88
        $now = date('Y-m-d H:i:s');
89
        foreach ($userSSEReloads as $sseMsg){
90
            $reloadSelectors[] = $sseMsg->data;
91
            if($delete && $now > date($sseMsg->deleteOn)){
92
                $sseMsg->delete();
93
            }
94
        }
95
        
96
        if(!empty($reloadSelectors)){
97
            $sseData .= '"reloadSelector":'.bab_json_encode($reloadSelectors);
98
            $hasData = true;
99
        }
100
        
101
        $userSSEBrowserNotifications = $this->select($this->user->is($user)->_AND_($this->type->is(AppSSE::TYPE_BROWSER_NOTIFICATION)));
102
        $browserNotifications = array();
103
        foreach ($userSSEBrowserNotifications as $sseMsg){
104
            $browserNotifications[] = $sseMsg->data;
105
            if($delete){
106
                $sseMsg->delete();
107
            }
108
        }
109
        
110
        if(!empty($browserNotifications)){
111
            if($hasData){
112
                $sseData .= ', ';
113
            }
114
            $sseData .= '"browserNotifications":'.bab_json_encode($browserNotifications);
115
            $hasData = true;
0 ignored issues
show
The assignment to $hasData is dead and can be removed.
Loading history...
116
        }
117
        
118
        $sseData .= '}';
119
        
120
        return $sseData;
121
    }
122
    
123
    /**
124
     * Create a SSE event to reload DOM elements identified with the $reloadSelection class
125
     * @param string $reloadSelector    The css class of the element to reload (ex: ".reload_this_element" )
126
     * @param mixed  $for               The user id or a list of users id. If null, current user will be used, if 'all', all connected users will be used
127
     */
128
    public function newReloadSelector($reloadSelector, $for = null)
129
    {
130
        $App = $this->App();
131
        $users = array();
132
        if(!isset($for)){
133
            $users[] = $App->getCurrentUser();
134
        }
135
        else if(!is_array($for)){
136
            if($for === 'all'){
137
                $users = $App->getLoggedUsers();
138
            }
139
            else{
140
                $users[] = $for;
141
            }
142
        }
143
        
144
        $deleteOn = self::getDeleteOn();
145
        foreach ($users as $user){
146
            $record = $this->newRecord();
147
            $record->user = $user;
148
            $record->data = $reloadSelector;
149
            $record->type = AppSSE::TYPE_RELOAD_SELECTOR;
150
            $record->deleteOn = $deleteOn;
151
            $record->save();
152
        }
153
        
154
        return true;
155
    }
156
    
157
    /**
158
     * Create a SSE event to send a notification to the client browser.
159
     * Data can have the following attributes :
160
     * title => The title of the notification (required).
161
     * body => The body of the notification (required).
162
     * icon => A url to an icon to be displayed in the notification, ideal size is 64x64 (optional).
163
     * action => A url which the user will be redirected to when clicking on the notification (optional).
164
     * @param array $data
165
     * @param mixed  $for   The user id of a list of users id. If null, current user will be used, if 'all', all connected users will be used
166
     */
167
    public function newBrowserNotification($data, $for = null)
168
    {
169
        $App = $this->App();
170
        $users = array();
171
        if(!isset($for)){
172
            $users[] = $App->getCurrentUser();
173
        }
174
        else if(!is_array($for)){
175
            if($for === 'all'){
176
                $users = $App->getLoggedUsers();
177
            }
178
            else{
179
                $users[] = $for;
180
            }
181
        }
182
        
183
        $deleteOn = self::getDeleteOn();
184
        foreach ($users as $user){
185
            $record = $this->newRecord();
186
            $record->user = $user;
187
            $record->data = bab_json_encode($data);
188
            $record->type = AppSSE::TYPE_BROWSER_NOTIFICATION;
189
            $record->deleteOn = $deleteOn;
190
            $record->save();
191
        }
192
        
193
        return true;
194
    }
195
    
196
    public static function getDeleteOn()
197
    {
198
        $registry = app_getRegistry();
199
        $registry->changeDirectory('configuration');
200
        $registry->changeDirectory('SSE');
201
        $refreshFrequency = $registry->getValue('refreshFrequency', 3);
202
        return date("Y-m-d H:i:s", strtotime("+$refreshFrequency sec"));
203
    }
204
}