Completed
Push — master ( 00c129...1c2b41 )
by Michael
04:02
created

StatsModel::save()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 2

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 24
ccs 14
cts 14
cp 1
rs 8.9713
cc 2
eloc 13
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Stats\Models;
4
5
use Joomla\Database\Query\LimitableInterface;
6
use Joomla\Model\AbstractDatabaseModel;
7
8
/**
9
 * Statistics database model
10
 *
11
 * @since  1.0
12
 */
13
class StatsModel extends AbstractDatabaseModel
14
{
15
	/**
16
	 * The query batch size
17
	 *
18
	 * @var    integer
19
	 * @since  1.0
20
	 */
21
	private $batchSize = 25000;
22
23
	/**
24
	 * Loads the statistics data from the database.
25
	 *
26
	 * @param   string  $column  A single column to filter on
27
	 *
28
	 * @return  \Generator  A Generator containing the response data
29
	 *
30
	 * @since   1.0
31
	 * @throws  \InvalidArgumentException
32
	 */
33 3
	public function getItems($column = null)
34
	{
35 3
		$db = $this->getDb();
36
37
		// Validate the requested column is actually in the table
38 3
		if ($column !== null)
39 3
		{
40 2
			$columnList = $db->getTableColumns('#__jstats');
41
42
			// The column should exist in the table and be part of the API
43 2
			if (!in_array($column, array_keys($columnList)) && !in_array($column, ['unique_id', 'modified']))
44 2
			{
45 1
				throw new \InvalidArgumentException('An invalid data source was requested.', 404);
46
			}
47
48 1
			$db->setQuery(
49 1
				$db->getQuery(true)
50 1
					->select($column)
51 1
					->from('#__jstats')
52 1
					->group('unique_id')
53 1
			);
54
55 1
			yield $db->loadAssocList();
56 1
		}
57
		else
58
		{
59
			// If fetching all data from the table, we need to break this down a fair bit otherwise we're going to run out of memory
60 1
			$totalRecords = $db->setQuery(
61 1
				$db->getQuery(true)
62 1
					->select('COUNT(unique_id)')
63 1
					->from('#__jstats')
64 1
			)->loadResult();
65
66 1
			$return = [];
0 ignored issues
show
Unused Code introduced by
$return 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
68 1
			$query = $db->getQuery(true)
69 1
				->select(['php_version', 'db_type', 'db_version', 'cms_version', 'server_os'])
70 1
				->from('#__jstats')
71 1
				->group('unique_id');
72
73 1
			$limitable = $query instanceof LimitableInterface;
74
75
			// We can't have this as a single array, we run out of memory... This is gonna get interesting...
76 1
			for ($offset = 0; $offset < $totalRecords; $offset + $this->batchSize)
77
			{
78
				if ($limitable)
79 1
				{
80
					$query->setLimit($this->batchSize, $offset);
81
82
					$db->setQuery($query);
83
				}
84
				else
85
				{
86 1
					$db->setQuery($query, $offset, $this->batchSize);
87
				}
88
89 1
				yield $db->loadAssocList();
90
91 1
				$offset += $this->batchSize;
92 1
			}
93
94
			// Disconnect the DB to free some memory
95 1
			$db->disconnect();
96
97
			// And unset some variables
98 1
			unset($db, $query, $offset, $totalRecords);
99
		}
100 2
	}
101
102
	/**
103
	 * Saves the given data.
104
	 *
105
	 * @param   \stdClass  $data  Data object to save.
106
	 *
107
	 * @return  void
108
	 *
109
	 * @since   1.0
110
	 */
111 2
	public function save($data)
112
	{
113 2
		$db = $this->getDb();
114
115
		// Set the modified date of the record
116 2
		$data->modified = (new \DateTime('now', new \DateTimeZone('UTC')))->format($db->getDateFormat());
117
118
		// Check if a row exists for this unique ID and update the existing record if so
119 2
		$recordExists = $db->setQuery(
120 2
			$db->getQuery(true)
121 2
				->select('unique_id')
122 2
				->from('#__jstats')
123 2
				->where('unique_id = ' . $db->quote($data->unique_id))
124 2
		)->loadResult();
125
126
		if ($recordExists)
127 2
		{
128 1
			$db->updateObject('#__jstats', $data, ['unique_id']);
129 1
		}
130
		else
131
		{
132 1
			$db->insertObject('#__jstats', $data, ['unique_id']);
0 ignored issues
show
Documentation introduced by
array('unique_id') is of type array<integer,string,{"0":"string"}>, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
133
		}
134 2
	}
135
}
136