1: <?php
2:
3: namespace NNV\OneSignal\API;
4:
5: use \NNV\OneSignal\OneSignal;
6: use \NNV\OneSignal\Utils\Validation;
7: use Symfony\Component\OptionsResolver\Options;
8:
9: 10: 11:
12: class Player
13: {
14: 15: 16: 17: 18:
19: private $oneSignal;
20:
21: 22: 23: 24: 25:
26: private $appIDKey;
27:
28: 29: 30: 31: 32:
33: private $restAPIKey;
34:
35: 36: 37: 38: 39:
40: private $extraOptions;
41:
42: 43: 44: 45: 46:
47: public function __construct(OneSignal $oneSignal, $appIDKey = null, $restAPIKey = null)
48: {
49: $this->oneSignal = $oneSignal;
50: $this->appIDKey = ($appIDKey ? $appIDKey : $oneSignal->getAppIDKey());
51: $this->restAPIKey = ($restAPIKey ? $restAPIKey : $oneSignal->getRESTAPIKey());
52: $this->extraOptions = [
53: 'headers' => [
54: 'Authorization' => sprintf('Basic %s', $this->restAPIKey),
55: ]
56: ];
57: }
58:
59: 60: 61: 62: 63: 64: 65:
66: public function all($limit = 10, $offset = 0)
67: {
68: $url = sprintf(
69: 'players?app_id=%s&limit=%s&offset=&%s',
70: $this->appIDKey,
71: $limit,
72: $offset
73: );
74: $devices = $this->oneSignal->execute($url, 'GET', $this->extraOptions);
75:
76: return $devices;
77: }
78:
79: 80: 81: 82: 83: 84:
85: public function get($playerID)
86: {
87: $url = sprintf('players/%s', $playerID);
88: $players = $this->oneSignal->execute($url, 'GET', $this->extraOptions);
89:
90: return $players;
91: }
92:
93: 94: 95: 96: 97: 98: 99:
100: public function create($deviceType, array $playerData)
101: {
102: $playerData = array_merge($playerData, [
103: 'app_id' => $this->appIDKey,
104: 'device_type' => $deviceType
105: ]);
106: $playerData = $this->validatePlayerData($playerData, $this->getPlayerDataRules());
107: $player = $this->oneSignal->execute('players', 'POST', [
108: 'form_params' => $playerData,
109: ]);
110:
111: return $player;
112: }
113:
114: 115: 116: 117: 118: 119: 120:
121: public function update($playerID, array $playerData)
122: {
123: $url = sprintf('players/%s', $playerID);
124: $playerData = array_merge($playerData, [
125: 'app_id' => $this->appIDKey,
126: ]);
127: $playerDataRules = $this->getPlayerDataRules();
128:
129: unset($playerDataRules['required'][1]);
130:
131: $playerData = $this->validatePlayerData($playerData, $playerDataRules);
132: $player = $this->oneSignal->execute($url, 'PUT', [
133: 'form_params' => $playerData,
134: ]);
135:
136: return $player;
137: }
138:
139: 140: 141: 142: 143: 144: 145:
146: public function onSession($playerID, array $sessionData)
147: {
148: $url = sprintf('players/%s/on_session', $playerID);
149: $playerSessionRules = $this->getPlayerDataRules();
150: $unnecessaryDefinedOptions = [
151: 'app_id', 'device_type', 'session_count',
152: 'amount_spent', 'created_at', 'playtime',
153: 'badge_count', 'last_active', 'notification_types',
154: 'test_type', 'long', 'lat', 'device_model',
155: ];
156: $playerSessionRules['required'] = [];
157: $sessionData = $this->validatePlayerData($sessionData, $playerSessionRules);
158:
159: foreach ($unnecessaryDefinedOptions as $definedOption) {
160: unset($sessionData[$definedOption]);
161: }
162:
163: $player = $this->oneSignal->execute($url, 'POST', [
164: 'form_params' => $sessionData,
165: ]);
166:
167: return $player;
168: }
169:
170: 171: 172: 173: 174: 175: 176: 177:
178: public function onPurchase($playerID, array $purchaseData, $isExisting = null)
179: {
180: $url = sprintf('players/%s/on_purchase', $playerID);
181: $purchaseDataRules = $this->getPurchaseDataRules();
182:
183: if (isset($purchaseData[0]) && !is_array($purchaseData[0])) {
184: $purchaseData = [$purchaseData];
185: }
186: foreach ($purchaseData as $purchase) {
187: $this->validatePurchaseData($purchase, $purchaseDataRules);
188: }
189:
190: $purchaseData = [
191: 'purchases' => $purchaseData,
192: ];
193:
194: if (is_bool($isExisting)) {
195: $purchaseData['existing'] = $isExisting;
196: }
197:
198: $purchase = $this->oneSignal->execute($url, 'POST', [
199: 'headers' => [
200: 'Content-Type' => 'application/json',
201: ],
202: 'json' => $purchaseData,
203: ]);
204:
205: return $purchase;
206: }
207:
208: 209: 210: 211: 212: 213: 214:
215: public function onFocus($playerID, array $focusData)
216: {
217: $url = sprintf('players/%s/on_focus', $playerID);
218: $onFocusDataRules = $this->getOnFocusDataRules();
219: $this->validateOnFocusData($focusData, $onFocusDataRules);
220:
221: $onFocus = $this->oneSignal->execute($url, 'POST', [
222: 'form_params' => $focusData,
223: ]);
224:
225: return $onFocus;
226: }
227:
228: 229: 230: 231: 232: 233:
234: public function csvExport(array $extraFields = [])
235: {
236: $url = sprintf('players/csv_export?app_id=%s', $this->appIDKey);
237:
238: if (count($extraFields)) {
239: $extraFields = [
240: 'extra_fields' => $extraFields,
241: ];
242: }
243:
244: return $this->oneSignal->execute($url, 'POST', array_merge([
245: 'form_params' => $extraFields,
246: ], $this->extraOptions));
247: }
248:
249: 250: 251: 252: 253:
254: private function getPlayerDataRules()
255: {
256: return [
257: 'required' => ['app_id', 'device_type'],
258: 'defined' => [
259: 'app_id' => 'string',
260: 'device_type' => [
261: 'allowedTypes' => 'int',
262: 'allowedValues' => range(0, 9),
263: ],
264: 'identifier' => 'string',
265: 'language' => 'string',
266: 'timezone' => 'int',
267: 'game_version' => 'string',
268: 'device_model' => 'string',
269: 'device_os' => 'string',
270: 'ad_id' => 'string',
271: 'sdk' => 'string',
272: 'session_count' => 'int',
273: 'tags' => 'array',
274: 'amount_spent' => 'string',
275: 'created_at' => 'int',
276: 'playtime' => 'init',
277: 'badge_count' => 'int',
278: 'last_active' => 'int',
279: 'notification_types' => [
280: 'allowedTypes' => 'string',
281: 'allowedValues' => [1, -2],
282: ],
283: 'test_type' => [
284: 'allowedTypes' => 'int',
285: 'allowedValues' => [1, 2],
286: ],
287: 'long' => 'double',
288: 'lat' => 'double',
289: ],
290: ];
291: }
292:
293: 294: 295: 296: 297:
298: private function getPurchaseDataRules()
299: {
300: return [
301: 'required' => ['sku', 'amount', 'iso'],
302: 'defined' => [
303: 'sku' => 'string',
304: 'amount' => 'string',
305: 'iso' => 'string',
306: 'existing' => 'bool',
307: ],
308: ];
309: }
310:
311: 312: 313: 314: 315:
316: private function getOnFocusDataRules()
317: {
318: return [
319: 'required' => ['state', 'active_time'],
320: 'defined' => [
321: 'state' => [
322: 'allowedTypes' => 'string',
323: 'allowedValues' => 'ping',
324: ],
325: 'active_time' => 'int',
326: ],
327: ];
328: }
329:
330: 331: 332: 333: 334: 335: 336:
337: private function validatePlayerData(array $playerData, array $playerDataRules)
338: {
339: $validation = new Validation();
340:
341: $validation->setMultiRequired($playerDataRules['required'])
342: ->setMultiDefined($playerDataRules['defined'])
343: ->setNormalizer('tags', function(Options $options, $tags) {
344: return json_decode(json_encode($tags));
345: })
346: ->setAllowedValues('amount_spent', function($amountSpent) {
347: return preg_match('/^\-?\d+(\.\d{1,2})?$/', $amountSpent);
348: });
349:
350: return $validation->validate($playerData);
351: }
352:
353: 354: 355: 356: 357: 358: 359:
360: private function validatePurchaseData(array $purchaseData, array $purchaseDataRules)
361: {
362: $validation = new Validation;
363:
364: $validation->setMultiRequired($purchaseDataRules['required'])
365: ->setMultiDefined($purchaseDataRules['defined'])
366: ->setAllowedValues('amount', function($amountSpent) {
367: return preg_match('/^\-?\d+(\.\d{1,2})?$/', $amountSpent);
368: });
369:
370: $validation->validate($purchaseData);
371: }
372:
373: 374: 375: 376: 377: 378: 379:
380: private function validateOnFocusData(array $onFocusData, array $onFocusDataRules)
381: {
382: $validation = new Validation;
383:
384: $validation->setMultiRequired($onFocusDataRules['required'])
385: ->setMultiDefined($onFocusDataRules['defined'])
386: ->validate($onFocusData);
387: }
388: }
389: