Kills::killMerge()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 11
rs 9.4285
cc 3
eloc 8
nc 3
nop 3
1
<?php
2
/* zKillboard
3
 * Copyright (C) 2012-2015 EVE-KILL Team and EVSCO.
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Affero General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Affero General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Affero General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
/**
20
 * General stuff for getting kills and manipulating them
21
 */
22
class Kills
23
{
24
	/**
25
	 * Gets killmails
26
	 *
27
	 * @param $parameters an array of parameters to fetch mails for
28
	 * @param $allTime gets all mails from the beginning of time or not
29
	 * @return array
30
	 */
31
	public static function getKills($parameters = array(), $allTime = true, $includeKillDetails = true)
32
	{
33
		$tables = array();
34
		$orWhereClauses = array();
35
		$andWhereClauses = array();
36
		Filters::buildFilters($tables, $orWhereClauses, $andWhereClauses, $parameters, $allTime);
37
38
		$tables = array_unique($tables);
39
		if (sizeof($tables) == 0) $tables[] = "zz_participants p";
40
		if (sizeof($tables) > 2) throw new Exception("More than 2 tables not supported yet");
41
42
		$tables = array_values($tables);
43
		$tablePrefix = substr($tables[0], strlen($tables[0]) - 1, 1);
44
		$tablePrefixOther = sizeof($tables) == 2 ? substr($tables[1], strlen($tables[1]) - 1, 1) : "p";
45
46
		$query = "select distinct ${tablePrefix}.killID from ";
47
		$query .= implode(" left join ", array_unique($tables));
48
		if (sizeof($tables) == 2) $query .= " on ($tablePrefix.killID = ${tablePrefixOther}.killID) ";
49
		if(isset($parameters["index"])) $query .= " use index (". $parameters["index"] . ") ";
50
		if (sizeof($andWhereClauses) || sizeof($orWhereClauses)) {
51
			$query .= " where ";
52
			if (sizeof($orWhereClauses) > 0) {
53
				$andOr = array_key_exists("combined", $parameters) && $parameters["combined"] == true ? " or " : " and ";
54
				$query .= " ( " . implode($andOr, $orWhereClauses) . " ) ";
55
				if (sizeof($andWhereClauses)) $query .= " and ";
56
			}
57
			if (sizeof($andWhereClauses)) $query .= implode(" and ", $andWhereClauses);
58
		}
59
60
		$limit = array_key_exists("limit", $parameters) ? (int)$parameters["limit"] : 100;
61
		$page = array_key_exists("page", $parameters) ? (int)$parameters["page"] : 1;
62
		$offset = ($page - 1) * $limit;
63
64
		if ($tablePrefix == "w") $orderBy = "w.killID";
65
		else $orderBy = array_key_exists("orderBy", $parameters) ? $parameters["orderBy"] : "${tablePrefix}.dttm";
66
		$orderDirection = array_key_exists("orderDirection", $parameters) ? $parameters["orderDirection"] : "desc";
0 ignored issues
show
Unused Code introduced by
$orderDirection is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
67
		$orderDirection = "desc"; // only desc
68
		$query .= " order by $orderBy $orderDirection limit $offset, $limit";
69
70
		// Is isVictim is used, no need to use distinct, since isVictim is already distinct
71
		if(stristr($query, "isVictim = '1'"))
72
			$query = str_replace("distinct", "", $query);
73
74
		// This is a war query, lets replace the entire thing
75
		if(isset($parameters["war"]))
76
			$query = "SELECT p.killID FROM zz_participants p WHERE p.killID IN (SELECT killID FROM zz_warmails WHERE warID = " . $parameters["war"] . ") AND p.isVictim = 1 ORDER BY $orderBy $orderDirection LIMIT $offset, $limit";
77
78
		$cacheTime = array_key_exists("cacheTime", $parameters) ? (int)$parameters["cacheTime"] : 120;
79
		$cacheTime = max(120, $cacheTime);
80
		if (array_key_exists("log", $parameters)) Db::log($query, array());
81
		$kills = Db::query($query, array(), $cacheTime);
82
		if ($includeKillDetails == false) return $kills;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
83
		$merged = self::getKillsDetails($kills);
84
		return $merged;
85
	}
86
87
	/**
88
	 * Gets details for kills
89
	 *
90
	 * @param $kills
91
	 * @return array
92
	 */
93
	public static function getKillsDetails($kills)
94
	{
95
		$merged = array();
96
		$killIDS = array();
97
98
		foreach ($kills as $kill) {
99
			$killIDS[] = $kill["killID"];
100
			$merged[$kill["killID"]] = array();
101
		}
102
103
		if (sizeof($killIDS)) {
104
			$imploded = implode(",", $killIDS);
105
			$victims = Db::query("select * from zz_participants where killID in ($imploded) and isVictim = 1", array(), 300);
106
			$finalBlows = Db::query("select * from zz_participants where killID in ($imploded) and finalBlow = 1", array(), 300);
107
			$info = $victims;
108
			$merged = self::killMerge($merged, "victim", $victims);
109
			$merged = self::killMerge($merged, "finalBlow", $finalBlows);
110
			$merged = self::killMerge($merged, "info", $info);
111
		}
112
		return $merged;
113
	}
114
115
	/**
116
	 * Merges killmail arrays
117
	 *
118
	 * @param $array1
119
	 * @param string $type
120
	 * @param $array2
121
	 * @return array
122
	 */
123
	private static function killMerge($array1, $type, $array2)
124
	{
125
		foreach ($array2 as $element) {
126
			$killid = $element["killID"];
127
			Info::addInfo($element);
128
			if (!isset($array1[$killid])) $array1[$killid] = array();
129
			$array1[$killid][$type] = $element;
130
			$array1[$killid][$type]["commentID"] = $killid;
131
		}
132
		return $array1;
133
	}
134
135
	/**
136
	 * Gets details for a kill
137
	 *
138
	 * @param $killID the killID of the kill you want details for
139
	 * @return array
140
	 */
141
	public static function getKillDetails($killID)
142
	{
143
		$victim = Db::queryRow("select * from zz_participants where killID = :killID and isVictim = 1", array(":killID" => $killID));
144
		$kill = $victim;
145
		$involved = Db::query("select * from zz_participants where killID = :killID and isVictim = 0 order by damage desc", array(":killID" => $killID));
146
		$items = self::getItems($killID);
147
148
		Info::addInfo($kill);
149
		Info::addInfo($victim);
150
		$infoInvolved = array();
151
		$infoItems = array();
152
		foreach ($involved as $i) $infoInvolved[] = Info::addInfo($i);
153
		unset($involved);
154
		foreach ($items as $i) $infoItems[] = Info::addInfo($i);
155
		unset($items);
156
157
		return array("info" => $kill, "victim" => $victim, "involved" => $infoInvolved, "items" => $infoItems);
158
	}
159
160
	public static function getItems($killID)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
161
	{
162
		$json = Killmail::get($killID);
163
		$killArray = json_decode($json, true);
164
		$killTime = $killArray["killTime"];
165
		$items = array();
166
		if(isset($killArray["items"]))
167
			self::addItems($items, $killArray["items"], $killTime);
168
		return $items;
169
	}
170
171
	public static function addItems(&$itemArray, $items, $killTime, $inContainer = 0, $parentFlag = 0) {
172
		if (is_array($items)) foreach ($items as $item) {
173
			$typeID = $item["typeID"];
174
			$item["price"] = Price::getItemPrice($typeID, $killTime);
175
			$item["inContainer"] = $inContainer;
176
			if ($inContainer) $item["flag"] = $parentFlag;
177
			if ($inContainer && strpos(Info::getItemName($typeID), "Blueprint")) $item["singleton"] = 2;
178
			unset($item["_stringValue"]);
179
			$itemArray[] = $item;
180
			$subItems = isset($item["items"]) ? $item["items"] : null;
181
			unset($item["items"]);
182
			if ($subItems != null) self::addItems($itemArray, $subItems, $killTime, 1, $item["flag"]);
183
		}
184
	}
185
186
	/**
187
	 * Merges two kill arrays together
188
	 *
189
	 * @param $array1
190
	 * @param $array2
191
	 * @param $maxSize
192
	 * @param $key
193
	 * @param $id
194
	 * @return array
195
	 */
196
	public static function mergeKillArrays($array1, $array2, $maxSize, $key, $id)
197
	{
198
		$maxSize = max(0, $maxSize);
199
		$resultArray = array_diff_key($array1, $array2) + $array2;
200
		while (sizeof($resultArray) > $maxSize) array_pop($resultArray);
201
		foreach ($resultArray as $killID => $kill) {
202
			if (!isset($kill["victim"])) continue;
203
			$victim = $kill["victim"];
204
			if ($victim[$key] == $id) $kill["displayAsLoss"] = true;
205
			else $kill["displayAsKill"] = true;
206
			$resultArray[$killID] = $kill;
207
		}
208
		return $resultArray;
209
	}
210
211
	/**
212
	 * Returns an array of the kill
213
	 *
214
	 * @param $killID the ID of the kill
215
	 * @return array
216
	 */
217
	public static function getArray($killID)
218
	{
219
		$jsonRaw = Killmail::get($killID);
220
		$decode = json_decode($jsonRaw, true);
221
		$killarray = Info::addInfo($decode);
222
		return $killarray;
223
	}
224
225
	/**
226
	 * Returns json of the kill
227
	 *
228
	 * @param $killID the ID of the kill
229
	 * @return string
230
	 */
231
	public static function getJson($killID)
232
	{
233
		$jsonRaw = Killmail::get($killID);
234
		$decoded = json_decode($jsonRaw, true);
235
		$killarray = Info::addInfo($decoded);
236
		return json_encode($killarray);
237
	}
238
239
	/**
240
	 * Returns a raw mail, that it gets from the getArray function
241
	 *
242
	 * @static
243
	 * @param $killID the ID of the kill
244
	 * @return string
245
	 */
246
	public static function getRawMail($killID, $array = array(), $edk = true)
247
	{
248
		$cacheName = $killID;
249
		$sem = Semaphore::fetch($killID);
250
		if($edk)
251
			$cacheName = $killID."EDK";
252
253
		// Check if the mail has already been generated, then return it from the cache..
254
		$Cache = Cache::get($cacheName);
255
		if($Cache) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Cache of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
256
			Semaphore::release($sem);
257
			return $Cache;
258
		}
259
260
		// Find all groupIDs where they contain Deadspace
261
		$deadspaceIDs = array();
262
		$dIDs = Db::query("SELECT groupID FROM ccp_invGroups WHERE groupName LIKE '%deadspace%' OR groupName LIKE 'FW%' OR groupName LIKE 'Asteroid%'");
263
		foreach($dIDs as $dd)
264
			$deadspaceIDs[] = $dd["groupID"];
265
266
		// ADD ALL THE FLAGS!!!!!!!!!!!
267
		//$flags = array("(Cargo)" => 5, "(Drone Bay)" => 87, "(Implant)" => 89);
268
		$dbFlags = Db::query("SELECT flagText, flagID FROM ccp_invFlags", array(), 3600);
269
		$flags = array();
270
		foreach($dbFlags as $f)
271
			$flags[(int) $f["flagID"]] = $f["flagText"];
272
273
		if(!$array)
0 ignored issues
show
Bug Best Practice introduced by
The expression $array of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
274
			$k = self::getArray($killID);
275
		else
276
			$k = $array;
277
278
		$mail = $k["killTime"] . "\n";
279
		$mail .= "\n";
280
		$mail .= "Victim: " . $k["victim"]["characterName"] . "\n";
281
		$mail .= "Corp: " . $k["victim"]["corporationName"] . "\n";
282
		if (!isset($k["victim"]["allianceName"]) || $k["victim"]["allianceName"] == "")
283
			$k["victim"]["allianceName"] = "None";
284
		$mail .= "Alliance: " . $k["victim"]["allianceName"] . "\n";
285
		if (!isset($k["victim"]["factionName"]) || $k["victim"]["factionName"] == "")
286
			$k["victim"]["factionName"] = "None";
287
		$mail .= "Faction: " . $k["victim"]["factionName"] . "\n";
288
		if (!isset($k["victim"]["shipName"]) || $k["victim"]["shipName"] == "")
289
			$k["victim"]["shipName"] = "None";
290
		$mail .= "Destroyed: " . $k["victim"]["shipName"] . "\n";
291
		if (!isset($k["solarSystemName"]) || $k["solarSystemName"] == "")
292
			$k["solarSystemName"] = "None";
293
		$mail .= "System: " . $k["solarSystemName"] . "\n";
294
		if (!isset($k["solarSystemSecurity"]) || $k["solarSystemSecurity"] == "")
295
			$k["solarSystemSecurity"] = (int) 0;
296
		$mail .= "Security: " . $k["solarSystemSecurity"] . "\n";
297
		if (!isset($k["victim"]["damageTaken"]) || $k["victim"]["damageTaken"] == "")
298
			$k["victim"]["damageTaken"] = (int) 0;
299
		$mail .= "Damage Taken: " . $k["victim"]["damageTaken"] . "\n\n";
300
		if(isset($k["attackers"]))
301
		{
302
			$mail .= "Involved parties:\n\n";
303
			foreach ($k["attackers"] as $inv)
304
			{
305
				// find groupID for the ship
306
				if(!isset($inv["shipName"])) $inv["shipName"] = "Unknown";
307
				$groupID = Db::queryField("SELECT groupID FROM ccp_invTypes WHERE typeName LIKE :shipName", "groupID", array(":shipName" => $inv["shipName"]));
308
				if(in_array($groupID, $deadspaceIDs))
309
				{
310
					// shipName isn't set, but it's an npc.. fml..
311
					if ($inv["finalBlow"] == 1)
312
						$mail .= "Name: ". $inv["shipName"] . " / " . $inv["corporationName"] . " (laid the final blow)\n";
313
					else
314
						$mail .= "Name: ". $inv["shipName"] . " / " . $inv["corporationName"] . "\n";
315
					$mail .= "Damage Done: " . $inv["damageDone"] . "\n\n";
316
				}
317
				else
318
				{
319
					if ($inv["finalBlow"] == 1)
320
						$mail .= "Name: " . $inv["characterName"] . " (laid the final blow)\n";
321
					else if (strlen($inv["characterName"]))
322
						$mail .= "Name: " . $inv["characterName"] . "\n";
323
					if (strlen($inv["characterName"])) $mail .= "Security: " . $inv["securityStatus"] . "\n";
324
					$mail .= "Corp: " . $inv["corporationName"] . "\n";
325
					if (!isset($inv["allianceName"]) || $inv["allianceName"] == "")
326
						$inv["allianceName"] = "None";
327
					$mail .= "Alliance: " . $inv["allianceName"] . "\n";
328
					if (!isset($inv["factionName"]) || $inv["factionName"] == "")
329
						$inv["factionName"] = "None";
330
					$mail .= "Faction: " . $inv["factionName"] . "\n";
331
					if (!isset($inv["shipName"]) || $inv["shipName"] == "")
332
						$inv["shipName"] = "None";
333
					$mail .= "Ship: " . $inv["shipName"] . "\n";
334
					if (!isset($inv["weaponName"]) || $inv["weaponName"] == "")
335
						$inv["weaponName"] = $inv["shipName"];
336
					$mail .= "Weapon: " . $inv["weaponName"] . "\n";
337
					$mail .= "Damage Done: " . $inv["damageDone"] . "\n\n";
338
				}
339
			}
340
		}
341
342
		$mail .= "\n";
343
		$dropped = array();
344
		$destroyed = array();
345
		if(isset($k["items"]))
346
		{
347
			foreach($k["items"] as $itm)
348
			{
349
				// Take the flags we get from $itemToSlot and replace it with the proper flag from the database
350
				if (!(isset($itm["flag"]) && isset($flags[$itm["flag"]]))) continue;
351
				$itm["flagName"] = $flags[$itm["flag"]];
352
353
				// create the flag!
354
				$copy = null;
355
				if($itm["singleton"] == 2)
356
					$copy = " (Copy)";
357
358
				$edkValidFlags = array("Cargo", "Drone Bay");
359
				if($edk && !in_array($itm["flagName"], $edkValidFlags))
360
					$flagName = null;
361
				else
362
					$flagName = " (". $itm["flagName"] . ")";
363
364
365
				if($itm["qtyDropped"]) // go to dropped list
366
				{
367
					$line = $itm["typeName"] . ", Qty: " . $itm["qtyDropped"] . $flagName . ($copy ? $copy : null);
368
					$dropped[] = $line;
369
				}
370
371
				if($itm["qtyDestroyed"]) // go to destroyed list
372
				{
373
					$line = $itm["typeName"] . ", Qty: " . $itm["qtyDestroyed"] . $flagName . ($copy ? $copy : null);
374
					$destroyed[] = $line;
375
				}
376
377
				if(isset($itm["items"]))
378
					foreach($itm["items"] as $key => $sub)
379
					{
380
						if($sub["qtyDropped"]) // go to dropped list
381
						{
382
							$line = $sub["typeName"] . ", Qty: " . $sub["qtyDropped"] . $flagName . ($copy ? $copy : null) . " (In Container)";
383
							$dropped[] = $line;
384
						}
385
						if($sub["qtyDestroyed"]) // go to destroyed list
386
						{
387
							$line = $sub["typeName"] . ", Qty: " . $sub["qtyDestroyed"] . $flagName . ($copy ? $copy : null) . " (In Container)";
388
							$destroyed[] = $line;
389
						}
390
					}
391
			}
392
		}
393
394
		if ($destroyed) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $destroyed of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
395
			$mail .= "Destroyed items:\n\n";
396
			foreach ($destroyed as $items)
397
				$mail .= $items . "\n";
398
		}
399
		$mail .= "\n";
400
		if ($dropped) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dropped of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
401
			$mail .= "Dropped items:\n\n";
402
			foreach ($dropped as $items)
403
				$mail .= $items . "\n";
404
		}
405
406
		// Store the generated mail in cache
407
		Cache::set($cacheName, $mail, 604800);
408
409
		Semaphore::release($sem);
410
		return $mail;
411
	}
412
413
	public static function cleanDupe($mKillID, $killID)
0 ignored issues
show
Unused Code introduced by
The parameter $killID is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
414
	{
415
		Db::execute("update zz_killmails set processed = 2 where killID = :mKillID", array(":mKillID" => $mKillID));
416
		Stats::calcStats($mKillID, false); // remove manual version from stats
417
	}
418
}
419