Completed
Branch FET-9795-new-interfaces (ea072c)
by
unknown
296:38 queued 279:44
created

ProgressStepManager::displaySteps()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace EventEspresso\core\services\progress_steps;
3
4
use EE_Request;
5
use  EventEspresso\core\exceptions\InvalidClassException;
6
use  EventEspresso\core\exceptions\InvalidDataTypeException;
7
use  EventEspresso\core\exceptions\InvalidIdentifierException;
8
use  EventEspresso\core\exceptions\InvalidInterfaceException;
9
use EventEspresso\core\services\collections\Collection;
10
use EventEspresso\core\services\collections\CollectionInterface;
11
use EventEspresso\core\services\progress_steps\display_strategies\ProgressStepsDisplayInterface;
12
13
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
14
	exit( 'No direct script access allowed' );
15
}
16
17
18
19
/**
20
 * Class ProgressStepManager
21
 * primarily used in conjunction with \EventEspresso\core\libraries\form_sections\form_handlers\SequentialStepFormManager
22
 * for displaying a visual guide that details all of the form steps within a sequence,
23
 * which steps have been completed, and which step is the currently active form
24
 *
25
 * @package       Event Espresso
26
 * @subpackage    core
27
 * @author        Brent Christensen
28
 * @since         4.9.0
29
 */
30
class ProgressStepManager {
31
32
	/**
33
	 * @var ProgressStepInterface[] $collection
34
	 */
35
	private $collection;
36
37
	/**
38
	 * @var string $default_step
39
	 */
40
	private $default_step;
41
42
	/**
43
	 * the key used for the URL param that denotes the current form step
44
	 * defaults to 'ee-form-step'
45
	 *
46
	 * @var string $form_step_url_key
47
	 */
48
	private $form_step_url_key = '';
49
50
	/**
51
	 * @var ProgressStepsDisplayInterface $display_strategy
52
	 */
53
	private $display_strategy;
54
55
	/**
56
	 * @var EE_Request $request
57
	 */
58
	private $request;
59
60
61
62
	/**
63
	 * ProgressStepManager constructor
64
	 *
65
	 * @param string              $display_strategy_name
66
	 * @param string              $default_step
67
	 * @param string              $form_step_url_key
68
	 * @param CollectionInterface $collection
69
	 * @param \EE_Request         $request
70
	 * @throws InvalidClassException
71
	 * @throws InvalidDataTypeException
72
	 * @throws InvalidInterfaceException
73
	 */
74
	public function __construct(
75
		$display_strategy_name = 'number_bubbles',
76
		$default_step = '',
77
		$form_step_url_key = '',
78
		CollectionInterface $collection = null,
79
		EE_Request $request = null
80
	) {
81
		$this->setDisplayStrategy( $display_strategy_name );
82
		$this->setDefaultStep( $default_step );
83
		$this->setFormStepUrlKey( $form_step_url_key );
84
		if ( ! $collection instanceof CollectionInterface ) {
85
			$collection = new Collection( '\EventEspresso\core\services\progress_steps\ProgressStepInterface' );
86
		}
87
		$this->collection = $collection;
0 ignored issues
show
Documentation Bug introduced by
It seems like $collection of type object<EventEspresso\cor...ns\CollectionInterface> is incompatible with the declared type array<integer,object<Eve...ProgressStepInterface>> of property $collection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
88
		if ( ! $request instanceof EE_Request ) {
89
			$request = \EE_Registry::instance()->load_core( 'Request' );
90
		}
91
		$this->request = $request;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request can also be of type boolean. However, the property $request is declared as type object<EE_Request>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
92
	}
93
94
95
96
	/**
97
	 * @param string $display_strategy_name
98
	 * @throws InvalidDataTypeException
99
	 * @throws InvalidClassException
100
	 */
101
	protected function setDisplayStrategy( $display_strategy_name = 'number_bubbles' ) {
102
		if ( ! is_string( $display_strategy_name ) ) {
103
			throw new InvalidDataTypeException( '$display_strategy_name', $display_strategy_name, 'string' );
104
		}
105
		// build up FQCN from incoming display strategy folder name
106
		$display_strategy_class = 'EventEspresso\core\services\progress_steps\display_strategies\\';
107
		$display_strategy_class .= $display_strategy_name . '\\';
108
		$display_strategy_class .= str_replace( ' ', '', ucwords( str_replace( '_', ' ', $display_strategy_name ) ) );
109
		$display_strategy_class .= 'ProgressStepsDisplay';
110
		$display_strategy_class = apply_filters(
111
			'FHEE__ProgressStepManager__setDisplayStrategy__display_strategy_class',
112
			$display_strategy_class
113
		);
114
		if ( ! class_exists( $display_strategy_class ) ) {
115
			throw new InvalidClassException( $display_strategy_class );
116
		}
117
		$display_strategy = new $display_strategy_class();
118
		if ( ! $display_strategy instanceof ProgressStepsDisplayInterface ) {
119
			throw new InvalidClassException(
120
				$display_strategy_class,
121
				sprintf(
122
					__( 'The "%1$s" Class needs to be an implementation of the "%1$s" Interface.', 'event_espresso' ),
123
					$display_strategy_class,
124
					'\EventEspresso\core\services\progress_steps\display_strategies\ProgressStepsDisplayInterface'
125
				)
126
			);
127
		}
128
		$this->display_strategy = $display_strategy;
129
	}
130
131
132
133
	/**
134
	 * @param string $default_step
135
	 * @throws InvalidDataTypeException
136
	 */
137
	public function setDefaultStep( $default_step ) {
138
		if ( ! is_string( $default_step ) ) {
139
			throw new InvalidDataTypeException( '$default_step', $default_step, 'string' );
140
		}
141
		$this->default_step = $default_step;
142
	}
143
144
145
146
	/**
147
	 * @param string $form_step_url_key
148
	 * @throws InvalidDataTypeException
149
	 */
150
	public function setFormStepUrlKey( $form_step_url_key = 'ee-form-step' ) {
151
		if ( ! is_string( $form_step_url_key ) ) {
152
			throw new InvalidDataTypeException( '$form_step_key', $form_step_url_key, 'string' );
153
		}
154
		$this->form_step_url_key = ! empty( $form_step_url_key ) ? $form_step_url_key : 'ee-form-step';
155
	}
156
157
158
159
	/**
160
	 * @param string $step
161
	 * @throws InvalidIdentifierException
162
	 */
163
	public function setCurrentStep( $step = '' ) {
164
		// use incoming value if it's set, otherwise use request param if it's set, otherwise use default
165
		$step = ! empty( $step )
166
			? $step
167
			: $this->request->get( $this->form_step_url_key, $this->default_step );
168
		// grab the step previously known as current, in case we need to revert
169
		$current_current_step = $this->collection->current();
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
170
		// verify that requested step exists
171
		if ( ! $this->collection->has( $step ) ) {
0 ignored issues
show
Bug introduced by
The method has cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
172
			throw new InvalidIdentifierException( $step, $this->default_step );
173
		}
174
		if ( $this->collection->setCurrent( $step ) ) {
0 ignored issues
show
Bug introduced by
The method setCurrent cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
175
			// if the old boss is the same as the new boss, then nothing changes
176
			if ( $this->collection->current() !== $current_current_step ) {
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
177
				$current_current_step->setIsCurrent( false );
178
			}
179
			$this->collection->current()->setIsCurrent();
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
180
		} else {
181
			$this->collection->setCurrent( $current_current_step->id() );
0 ignored issues
show
Bug introduced by
The method setCurrent cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
182
			$current_current_step->setIsCurrent( true );
183
		}
184
	}
185
186
187
188
	/**
189
	 * setPreviousStepsCompleted
190
	 */
191
	public function setPreviousStepsCompleted() {
192
		$current_current_step = $this->collection->current();
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
193
		$this->collection->rewind();
0 ignored issues
show
Bug introduced by
The method rewind cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
194
		while ( $this->collection->valid() ) {
0 ignored issues
show
Bug introduced by
The method valid cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
195
			if ( $this->collection->current() === $current_current_step ) {
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
196
				break;
197
			}
198
			$this->setCurrentStepCompleted();
199
			$this->collection->next();
0 ignored issues
show
Bug introduced by
The method next cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
200
		}
201
		$this->collection->setCurrentUsingObject( $current_current_step );
0 ignored issues
show
Bug introduced by
The method setCurrentUsingObject cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
202
		return false;
203
	}
204
205
206
207
	/**
208
	 * @return ProgressStepInterface
209
	 */
210
	public function currentStep() {
211
		return $this->collection->current();
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
212
	}
213
214
215
216
	/**
217
	 * @return ProgressStepInterface
218
	 */
219
	public function nextStep() {
220
		return $this->collection->next();
0 ignored issues
show
Bug introduced by
The method next cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
221
	}
222
223
224
225
	/**
226
	 * @return void
227
	 */
228
	public function enqueueStylesAndScripts() {
229
		$this->display_strategy->enqueueStylesAndScripts();
230
	}
231
232
233
234
	/**
235
	 * echos out HTML
236
	 *
237
	 * @return string
238
	 */
239
	public function displaySteps() {
240
		return \EEH_Template::display_template(
241
			$this->display_strategy->getTemplate(),
242
			array( 'progress_steps' => $this->collection ),
243
			true
244
		);
245
	}
246
247
248
249
	/**
250
	 * @param bool $completed
251
	 * @return \EventEspresso\core\services\progress_steps\ProgressStepInterface
252
	 */
253
	public function setCurrentStepCompleted( $completed = true ) {
254
		return $this->collection->current()->setIsCompleted( $completed );
0 ignored issues
show
Bug introduced by
The method current cannot be called on $this->collection (of type array<integer,object<Eve...ProgressStepInterface>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
255
	}
256
257
258
259
}
260
261
// End of file ProgressStepManager.php
262
// Location: core/services/progress_steps/ProgressStepManager.php