Passed
Push — master ( f13f78...5c1b24 )
by Ismayil
04:22
created

engine/classes/Elgg/BatchUpgrader.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Elgg;
4
5
use Elgg\Upgrade\Batch;
6
use ElggUpgrade;
7
use Elgg\Upgrade\Result;
8
9
/**
10
 * Runs long running upgrades and gives feedback to UI after each batch.
11
 *
12
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
13
 *
14
 * @access private
15
 *
16
 * @since 3.0.0
17
 */
18
class BatchUpgrader {
19
20
	/**
21
	 * @var $config Config
22
	 */
23
	private $config;
24
25
	/**
26
	 * Constructor
27
	 *
28
	 * @param Config $config Site configuration
29
	 */
30 5
	public function __construct(Config $config) {
31 5
		$this->config = $config;
32
33
		// Custom limit can be defined in settings.php if necessary
34 5
		if (empty($this->config->batch_run_time_in_secs)) {
35 5
			$this->config->batch_run_time_in_secs = 4;
36
		}
37 5
	}
38
39
	/**
40
	 * Call the upgrade's run() for a short period of time, or until it completes
41
	 *
42
	 * @param ElggUpgrade $upgrade Upgrade to run
43
	 * @return array
44
	 * @throws \RuntimeException
45
	 */
46 4
	public function run(ElggUpgrade $upgrade) {
47
		// Upgrade also disabled data, so the compatibility is
48
		// preserved in case the data ever gets enabled again
49 4
		$ha = access_get_show_hidden_status();
50 4
		access_show_hidden_entities(true);
51
52 4
		$started = microtime(true);
53
54
		// Get the class taking care of the actual upgrading
55 4
		$batch = $upgrade->getBatch();
56
			
57 4
		if (!$batch) {
58
			throw new \RuntimeException(elgg_echo('admin:upgrades:error:invalid_batch', [$upgrade->title, $upgrade->guid]));
59
		}
60
61 4
		$count = $batch->countItems();
62
		
63 4
		$batch_failure_count = 0;
64 4
		$batch_success_count = 0;
65 4
		$errors = [];
66
67 4
		$processed = (int) $upgrade->processed;
68 4
		$offset = (int) $upgrade->offset;
69 4
		$has_errors = (bool) $upgrade->has_errors;
70
71
		/** @var Result $result */
72 4
		$result = null;
73
74 4
		$condition = function () use (&$count, &$processed, &$result, $started) {
75 4
			if ((microtime(true) - $started) >= $this->config->batch_run_time_in_secs) {
76
				return false;
77
			}
78 4
			if ($result && $result->wasMarkedComplete()) {
79 1
				return false;
80
			}
81
82 4
			return ($count === Batch::UNKNOWN_COUNT || ($count > $processed));
83 4
		};
84
		
85 4
		while ($condition()) {
86 4
			$result = $batch->run(new Result(), $offset);
87
88 4
			$failure_count = $result->getFailureCount();
89 4
			$success_count = $result->getSuccessCount();
90
91 4
			$batch_failure_count += $failure_count;
92 4
			$batch_success_count += $success_count;
93
94 4
			$total = $failure_count + $success_count;
95
			
96 4
			if ($batch->needsIncrementOffset()) {
97
				// Offset needs to incremented by the total amount of processed
98
				// items so the upgrade we won't get stuck upgrading the same
99
				// items over and over.
100 3
				$offset += $total;
101
			} else {
102
				// Offset doesn't need to be incremented, so we mark only
103
				// the items that caused a failure.
104 1
				$offset += $failure_count;
105
			}
106
107 4
			if ($failure_count > 0) {
108 3
				$has_errors = true;
109
			}
110
111 4
			$processed += $total;
112
113 4
			$errors = array_merge($errors, $result->getErrors());
114
		}
115
116 4
		access_show_hidden_entities($ha);
117
118 4
		$upgrade->processed = $processed;
119 4
		$upgrade->offset = $offset;
1 ignored issue
show
The property offset does not exist on object<ElggUpgrade>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
120 4
		$upgrade->has_errors = $has_errors;
1 ignored issue
show
The property has_errors does not exist on object<ElggUpgrade>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
121
		
122 4
		$completed = ($result && $result->wasMarkedComplete()) || ($processed >= $count);
123 4
		if ($completed) {
124
			// Upgrade is finished
125 4
			if ($has_errors) {
126
				// The upgrade was finished with errors. Reset offset
127
				// and errors so the upgrade can start from a scratch
128
				// if attempted to run again.
129 3
				$upgrade->processed = 0;
130 3
				$upgrade->offset = 0;
131 3
				$upgrade->has_errors = false;
132
			} else {
133
				// Everything has been processed without errors
134
				// so the upgrade can be marked as completed.
135 1
				$upgrade->setCompleted();
136
			}
137
		}
138
139
		// Give feedback to the user interface about the current batch.
140
		return [
141 4
			'errors' => $errors,
142 4
			'numErrors' => $batch_failure_count,
143 4
			'numSuccess' => $batch_success_count,
144 4
			'isComplete' => $result && $result->wasMarkedComplete(),
145
		];
146
	}
147
148
}
149